From b949037fa5bc5074bc30880fb639550eaed30a6d Mon Sep 17 00:00:00 2001 From: Wuesteon Date: Mon, 15 Dec 2025 17:53:52 +0100 Subject: [PATCH 01/28] =?UTF-8?q?=F0=9F=94=A7=20chore:=20add=20svelte-chec?= =?UTF-8?q?k=20to=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add automatic svelte-check validation for staged Svelte files: - Create svelte-check-staged.sh that runs on affected web apps only - Create build-check-staged.sh for production build validation - Integrate svelte-check into pre-commit hook - Add optional pre-push hook for full build checks - Update lint-staged config to handle Svelte files separately --- .husky/pre-commit | 3 + .husky/pre-push | 3 + lint-staged.config.js | 7 ++- package.json | 3 + scripts/build-check-staged.sh | 107 +++++++++++++++++++++++++++++++++ scripts/svelte-check-staged.sh | 73 ++++++++++++++++++++++ 6 files changed, 195 insertions(+), 1 deletion(-) create mode 100755 .husky/pre-push create mode 100755 scripts/build-check-staged.sh create mode 100755 scripts/svelte-check-staged.sh diff --git a/.husky/pre-commit b/.husky/pre-commit index ee2ec94c8..30c1cf220 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,2 +1,5 @@ pnpm exec lint-staged pnpm run type-check + +# Run svelte-check on staged web apps (catches a11y, imports, Svelte 5 issues) +./scripts/svelte-check-staged.sh diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100755 index 000000000..58a8531d3 --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,3 @@ +# Optional: Run production build check before push +# Uncomment to enable (slower but catches all CI issues) +# ./scripts/build-check-staged.sh diff --git a/lint-staged.config.js b/lint-staged.config.js index 308ffddc9..94417196d 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -3,5 +3,10 @@ export default { 'eslint --fix --ignore-pattern "apps-archived/**"', 'prettier --config .prettierrc.json --write', ], - '*.{json,md,svelte,astro}': ['prettier --config .prettierrc.json --write'], + '*.{json,md,astro}': ['prettier --config .prettierrc.json --write'], + // Svelte files: format + check for a11y and Svelte 5 issues + '*.svelte': [ + 'prettier --config .prettierrc.json --write', + // svelte-check is run at project level via pre-commit hook + ], }; diff --git a/package.json b/package.json index 1676ac859..dff273c23 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,9 @@ "clean": "turbo run clean", "format": "prettier --config .prettierrc.json --write \"**/*.{ts,tsx,js,jsx,json,md,svelte,astro}\"", "format:check": "prettier --config .prettierrc.json --check \"**/*.{ts,tsx,js,jsx,json,md,svelte,astro}\"", + "svelte-check": "./scripts/svelte-check-staged.sh", + "build:check": "./scripts/build-check-staged.sh", + "build:check:all": "./scripts/build-check-staged.sh --all", "setup:env": "node scripts/generate-env.mjs", "setup:db": "./scripts/setup-databases.sh", "setup:db:chat": "./scripts/setup-databases.sh chat", diff --git a/scripts/build-check-staged.sh b/scripts/build-check-staged.sh new file mode 100755 index 000000000..e391cadb5 --- /dev/null +++ b/scripts/build-check-staged.sh @@ -0,0 +1,107 @@ +#!/bin/bash +# Run production builds on web apps that have changes since main/dev +# This catches issues that only appear in production builds +# +# Usage: +# ./scripts/build-check-staged.sh # Check changes vs origin/dev +# ./scripts/build-check-staged.sh main # Check changes vs origin/main +# ./scripts/build-check-staged.sh --all # Check all web apps + +set -e + +BASE_BRANCH="${1:-origin/dev}" + +# Handle --all flag +if [ "$1" = "--all" ]; then + echo "πŸ”¨ Building ALL web apps..." + APPS_TO_BUILD=( + "apps/todo/apps/web" + "apps/chat/apps/web" + "apps/calendar/apps/web" + "apps/clock/apps/web" + "apps/manacore/apps/web" + "apps/contacts/apps/web" + "apps/zitare/apps/web" + "apps/picture/apps/web" + "apps/manadeck/apps/web" + ) +else + echo "πŸ” Finding changed files since $BASE_BRANCH..." + + # Get list of changed files + CHANGED_FILES=$(git diff --name-only "$BASE_BRANCH"...HEAD 2>/dev/null || git diff --name-only HEAD~10...HEAD) + + if [ -z "$CHANGED_FILES" ]; then + echo "No changes detected" + exit 0 + fi + + # Find unique web app directories that have changes + declare -A WEB_APPS + + for file in $CHANGED_FILES; do + # Direct changes in web app + if [[ $file =~ ^(apps/[^/]+/apps/web)/ ]]; then + WEB_APPS["${BASH_REMATCH[1]}"]=1 + elif [[ $file =~ ^(games/[^/]+/apps/web)/ ]]; then + WEB_APPS["${BASH_REMATCH[1]}"]=1 + # Changes in shared packages affect all web apps using them + elif [[ $file =~ ^packages/shared- ]]; then + echo "⚠️ Shared package changed: $file" + echo " All web apps may be affected" + # Add major web apps + WEB_APPS["apps/todo/apps/web"]=1 + WEB_APPS["apps/chat/apps/web"]=1 + WEB_APPS["apps/calendar/apps/web"]=1 + WEB_APPS["apps/manacore/apps/web"]=1 + fi + done + + APPS_TO_BUILD=("${!WEB_APPS[@]}") +fi + +if [ ${#APPS_TO_BUILD[@]} -eq 0 ]; then + echo "No web app changes detected" + exit 0 +fi + +echo "" +echo "πŸ”¨ Building affected web apps..." +echo " Apps: ${APPS_TO_BUILD[*]}" +echo "" + +# First build shared packages (needed for web apps) +echo "━━━ Building shared packages ━━━" +pnpm run build:packages || { + echo "❌ Failed to build shared packages" + exit 1 +} + +FAILED=0 + +for app in "${APPS_TO_BUILD[@]}"; do + if [ -f "$app/package.json" ]; then + echo "" + echo "━━━ Building $app ━━━" + + PKG_NAME=$(node -p "require('./$app/package.json').name" 2>/dev/null || echo "") + + if [ -n "$PKG_NAME" ]; then + if ! pnpm --filter "$PKG_NAME" build 2>&1; then + echo "❌ Build failed for $app" + FAILED=1 + else + echo "βœ… Build passed for $app" + fi + fi + fi +done + +if [ $FAILED -eq 1 ]; then + echo "" + echo "❌ Build check failed! Fix the issues above before pushing." + exit 1 +fi + +echo "" +echo "βœ… All builds passed!" diff --git a/scripts/svelte-check-staged.sh b/scripts/svelte-check-staged.sh new file mode 100755 index 000000000..9ed1caf78 --- /dev/null +++ b/scripts/svelte-check-staged.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# Run svelte-check on web apps that have staged .svelte files +# This catches a11y warnings, Svelte 5 issues, and import errors before CI + +set -e + +# Get list of staged svelte files +STAGED_SVELTE=$(git diff --cached --name-only --diff-filter=ACM | grep '\.svelte$' || true) + +if [ -z "$STAGED_SVELTE" ]; then + echo "No staged .svelte files, skipping svelte-check" + exit 0 +fi + +# Find unique web app directories that have changes +declare -A WEB_APPS + +for file in $STAGED_SVELTE; do + # Extract the web app path (e.g., apps/todo/apps/web) + if [[ $file =~ ^(apps/[^/]+/apps/web)/ ]]; then + WEB_APPS["${BASH_REMATCH[1]}"]=1 + elif [[ $file =~ ^(games/[^/]+/apps/web)/ ]]; then + WEB_APPS["${BASH_REMATCH[1]}"]=1 + elif [[ $file =~ ^(packages/[^/]+)/ ]]; then + # For shared packages, check all web apps that might use them + # This is a simplified approach - just warn + echo "⚠️ Changes in shared package: $file" + echo " Consider running: pnpm run build:check to verify all web apps" + fi +done + +if [ ${#WEB_APPS[@]} -eq 0 ]; then + echo "No web app changes detected" + exit 0 +fi + +echo "πŸ” Running svelte-check on affected web apps..." +FAILED=0 + +for app in "${!WEB_APPS[@]}"; do + if [ -f "$app/package.json" ]; then + echo "" + echo "━━━ Checking $app ━━━" + + # Get the package name for pnpm filter + PKG_NAME=$(node -p "require('./$app/package.json').name" 2>/dev/null || echo "") + + if [ -n "$PKG_NAME" ]; then + # Run svelte-check with threshold to fail on warnings + if ! pnpm --filter "$PKG_NAME" exec svelte-check --tsconfig ./tsconfig.json --threshold warning 2>&1; then + echo "❌ svelte-check failed for $app" + FAILED=1 + else + echo "βœ… svelte-check passed for $app" + fi + fi + fi +done + +if [ $FAILED -eq 1 ]; then + echo "" + echo "❌ svelte-check failed! Fix the issues above before committing." + echo "" + echo "Common fixes:" + echo " - Add role and tabindex to interactive divs" + echo " - Add onkeydown handler alongside onclick" + echo " - Use \$state() for reactive variables in Svelte 5" + echo " - Check that all imports resolve correctly" + exit 1 +fi + +echo "" +echo "βœ… All svelte-checks passed!" From 42e5e97390e7c4a23b7fa146e336afdc62538167 Mon Sep 17 00:00:00 2001 From: Wuesteon Date: Mon, 15 Dec 2025 19:09:01 +0100 Subject: [PATCH 02/28] =?UTF-8?q?=E2=99=BF=EF=B8=8F=20fix:=20resolve=20all?= =?UTF-8?q?=20svelte-check=20a11y=20warnings=20across=20web=20apps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix 121 accessibility warnings across 9 web apps (manacore, clock, chat, manadeck, calendar, zitare, contacts, picture, todo) - Add proper ARIA attributes (role, tabindex, aria-label) to interactive elements - Add onkeydown handlers alongside onclick for keyboard accessibility - Add svelte-ignore comments for intentional patterns (modals, dropdowns) - Update svelte-check threshold from error to warning in pre-commit hook - Fix script compatibility for bash 3.x (remove associative arrays) - Add comprehensive documentation for svelte-check patterns and fixes All web apps now pass svelte-check with 0 errors and 0 warnings. Pre-commit hooks will block any future commits with warnings. --- .../components/calendar/CalendarHeader.svelte | 2 +- .../calendar/CalendarToolbarContent.svelte | 6 + .../components/calendar/TagStripModal.svelte | 12 +- .../components/calendar/ViewModePill.svelte | 12 + .../calendar/ViewModePillContextMenu.svelte | 4 +- .../components/event/QuickEventOverlay.svelte | 9 - .../lib/components/tags/GroupedTagList.svelte | 13 +- .../web/src/lib/stores/calendars.svelte.ts | 1 + .../apps/web/src/lib/stores/search.svelte.ts | 3 +- .../src/routes/(app)/settings/+page.svelte | 6 + .../src/routes/(app)/statistics/+page.svelte | 13 +- .../components/chat/ConversationList.svelte | 1 + .../components/templates/TemplateForm.svelte | 10 +- .../apps/web/src/lib/stores/auth.svelte.ts | 6 +- .../routes/(protected)/settings/+page.svelte | 21 +- .../routes/(protected)/templates/+page.svelte | 6 +- apps/chat/packages/chat-types/src/index.ts | 6 +- apps/clock/apps/web/src/lib/api/feedback.ts | 23 ++ .../life-clock/CircularProgress.svelte | 3 +- .../apps/web/src/routes/(app)/+layout.svelte | 6 +- .../web/src/routes/(app)/alarms/+page.svelte | 26 +- .../src/routes/(app)/feedback/+page.svelte | 28 +- .../web/src/routes/(app)/mana/+page.svelte | 12 +- .../web/src/routes/(app)/profile/+page.svelte | 22 +- .../src/routes/(app)/settings/+page.svelte | 2 +- .../src/routes/(app)/stopwatch/+page.svelte | 4 + .../web/src/routes/(app)/themes/+page.svelte | 2 +- .../web/src/routes/(app)/timers/+page.svelte | 1 + .../src/routes/(app)/world-clock/+page.svelte | 7 +- .../(auth)/forgot-password/+page.svelte | 39 ++- .../src/routes/(auth)/register/+page.svelte | 41 ++- .../lib/components/ContactDetailModal.svelte | 15 +- .../web/src/lib/components/ContactList.svelte | 1 + .../src/lib/components/ContactNotes.svelte | 6 - .../web/src/lib/components/FilterBar.svelte | 24 +- .../web/src/lib/components/SearchModal.svelte | 4 +- .../lib/components/export/ExportModal.svelte | 13 +- .../components/network/NetworkGraph.svelte | 3 + .../views/ContactNetworkView.svelte | 1 + .../web/src/routes/(app)/archive/+page.svelte | 22 -- apps/manacore/apps/web/src/app.d.ts | 10 +- .../apps/web/src/lib/components/Icon.svelte | 31 +- .../widgets/CalendarEventsWidget.svelte | 12 +- .../dashboard/widgets/ChatRecentWidget.svelte | 12 +- .../widgets/ClockTimersWidget.svelte | 12 +- .../widgets/ContactsFavoritesWidget.svelte | 12 +- .../dashboard/widgets/CreditsWidget.svelte | 12 +- .../widgets/ManadeckProgressWidget.svelte | 16 +- .../widgets/PictureRecentWidget.svelte | 12 +- .../dashboard/widgets/ReferralWidget.svelte | 12 +- .../dashboard/widgets/TasksTodayWidget.svelte | 12 +- .../widgets/TasksUpcomingWidget.svelte | 12 +- .../widgets/TransactionsWidget.svelte | 12 +- .../widgets/ZitareQuoteWidget.svelte | 14 +- .../(app)/organizations/+page.server.ts | 12 +- .../routes/(app)/organizations/+page.svelte | 11 +- .../src/routes/(app)/teams/+page.server.ts | 15 +- .../web/src/routes/(app)/teams/+page.svelte | 9 +- .../apps/web/src/routes/+layout.svelte | 6 +- .../manacore/apps/web/src/routes/+page.svelte | 11 +- apps/manacore/apps/web/svelte.config.js | 4 + .../apps/web/src/lib/components/Icon.svelte | 34 --- .../components/deck/CreateDeckModal.svelte | 17 +- .../apps/web/src/routes/(app)/+layout.svelte | 2 +- .../web/src/routes/(app)/decks/+page.svelte | 2 +- .../src/routes/(app)/decks/[id]/+page.svelte | 6 + .../board/ImagePropertiesPanel.svelte | 88 +++--- .../gallery/ImageDetailModal.svelte | 28 +- .../generate/AdvancedSettingsModal.svelte | 87 +++--- .../src/lib/components/ui/ContextMenu.svelte | 6 + .../ui/KeyboardShortcutsModal.svelte | 3 + .../src/lib/components/upload/DropZone.svelte | 2 + .../apps/web/src/routes/app/tags/+page.svelte | 18 +- .../src/lib/components/QuickAddTask.svelte | 27 +- .../src/lib/components/TaskEditModal.svelte | 30 +- .../web/src/lib/components/TaskItem.svelte | 2 +- .../web/src/lib/components/TodoToolbar.svelte | 43 ++- .../lib/components/form/TagSelector.svelte | 9 +- .../components/kanban/AddColumnButton.svelte | 1 + .../kanban/KanbanColumnHeader.svelte | 4 + .../components/kanban/KanbanFilters.svelte | 11 +- .../components/kanban/KanbanTaskCard.svelte | 14 +- .../kanban/QuickAddTaskInline.svelte | 2 + .../apps/web/src/routes/(app)/+layout.svelte | 3 - .../web/src/routes/(app)/kanban/+page.svelte | 20 +- .../web/src/routes/(app)/network/+page.svelte | 10 +- .../web/src/lib/components/AuthorCard.svelte | 2 + .../web/src/routes/(app)/authors/+page.svelte | 22 -- .../web/src/routes/(app)/lists/+page.svelte | 37 +-- .../src/routes/(app)/lists/[id]/+page.svelte | 35 ++- .../web/src/routes/(app)/search/+page.svelte | 1 + docs/SVELTE_CHECK_ISSUES.md | 267 ++++++++++++++++++ packages/shared-auth/src/core/jwtUtils.ts | 1 + packages/shared-auth/src/types/index.ts | 1 + .../src/components/ResizeHandle.svelte | 5 +- packages/shared-ui/src/atoms/Button.svelte | 10 +- .../src/context-menu/ContextMenu.svelte | 11 +- .../src/molecules/ConfirmationPopover.svelte | 16 +- packages/shared-ui/src/molecules/Input.svelte | 6 + .../organisms/network/NetworkControls.svelte | 1 + scripts/svelte-check-staged.sh | 27 +- 101 files changed, 1048 insertions(+), 558 deletions(-) create mode 100644 apps/clock/apps/web/src/lib/api/feedback.ts delete mode 100644 apps/manadeck/apps/web/src/lib/components/Icon.svelte create mode 100644 docs/SVELTE_CHECK_ISSUES.md diff --git a/apps/calendar/apps/web/src/lib/components/calendar/CalendarHeader.svelte b/apps/calendar/apps/web/src/lib/components/calendar/CalendarHeader.svelte index 9ee69b7d8..8475bdc3c 100644 --- a/apps/calendar/apps/web/src/lib/components/calendar/CalendarHeader.svelte +++ b/apps/calendar/apps/web/src/lib/components/calendar/CalendarHeader.svelte @@ -94,11 +94,11 @@ } + diff --git a/apps/calendar/apps/web/src/lib/components/calendar/CalendarToolbarContent.svelte b/apps/calendar/apps/web/src/lib/components/calendar/CalendarToolbarContent.svelte index af591ef61..7e786232d 100644 --- a/apps/calendar/apps/web/src/lib/components/calendar/CalendarToolbarContent.svelte +++ b/apps/calendar/apps/web/src/lib/components/calendar/CalendarToolbarContent.svelte @@ -19,13 +19,19 @@ // View type labels const viewLabels: Record = { day: 'Tag', + '3day': '3 Tage', '5day': '5 Tage', week: 'Woche', '10day': '10 Tage', '14day': '14 Tage', + '30day': '30 Tage', + '60day': '60 Tage', + '90day': '90 Tage', + '365day': '365 Tage', month: 'Monat', year: 'Jahr', agenda: 'Agenda', + custom: 'Benutzerdefiniert', }; // Views to show in selector diff --git a/apps/calendar/apps/web/src/lib/components/calendar/TagStripModal.svelte b/apps/calendar/apps/web/src/lib/components/calendar/TagStripModal.svelte index 6a4e6ea3a..b40b27e8c 100644 --- a/apps/calendar/apps/web/src/lib/components/calendar/TagStripModal.svelte +++ b/apps/calendar/apps/web/src/lib/components/calendar/TagStripModal.svelte @@ -421,6 +421,7 @@
+
- - {#each eventTagGroupsStore.groups as group (group.id)} @@ -471,6 +472,7 @@
+
- - {#each eventTagGroupsStore.groups as group (group.id)} @@ -524,6 +526,7 @@
+
+ = { day: '1', + '3day': '3', '5day': '5', week: '7', '10day': '10', '14day': '14', + '30day': '30', + '60day': '60', + '90day': '90', + '365day': '365', month: 'M', year: 'Y', agenda: 'A', + custom: '', }; // View titles for tooltip const viewTitles: Record = { day: 'Tagesansicht', + '3day': '3-Tage-Ansicht', '5day': '5-Tage-Ansicht', week: 'Wochenansicht', '10day': '10-Tage-Ansicht', '14day': '14-Tage-Ansicht', + '30day': '30-Tage-Ansicht', + '60day': '60-Tage-Ansicht', + '90day': '90-Tage-Ansicht', + '365day': '365-Tage-Ansicht', month: 'Monatsansicht', year: 'Jahresansicht', agenda: 'Agenda', + custom: 'Benutzerdefiniert', }; // Get enabled views from settings diff --git a/apps/calendar/apps/web/src/lib/components/calendar/ViewModePillContextMenu.svelte b/apps/calendar/apps/web/src/lib/components/calendar/ViewModePillContextMenu.svelte index 38d43c725..01233cba1 100644 --- a/apps/calendar/apps/web/src/lib/components/calendar/ViewModePillContextMenu.svelte +++ b/apps/calendar/apps/web/src/lib/components/calendar/ViewModePillContextMenu.svelte @@ -183,9 +183,10 @@ {#if visible} - + + {#if onEditGroup} {/if} - +
{#if isExpanded(group.id)} diff --git a/apps/calendar/apps/web/src/lib/stores/calendars.svelte.ts b/apps/calendar/apps/web/src/lib/stores/calendars.svelte.ts index bf9489a31..ae9b5e87b 100644 --- a/apps/calendar/apps/web/src/lib/stores/calendars.svelte.ts +++ b/apps/calendar/apps/web/src/lib/stores/calendars.svelte.ts @@ -20,6 +20,7 @@ const birthdayCalendar: Calendar = { color: BIRTHDAY_CALENDAR.color, isDefault: false, isVisible: true, // Visibility controlled by settingsStore.showBirthdays + timezone: 'UTC', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; diff --git a/apps/calendar/apps/web/src/lib/stores/search.svelte.ts b/apps/calendar/apps/web/src/lib/stores/search.svelte.ts index 64c93eddb..8c3c2c924 100644 --- a/apps/calendar/apps/web/src/lib/stores/search.svelte.ts +++ b/apps/calendar/apps/web/src/lib/stores/search.svelte.ts @@ -4,7 +4,8 @@ interface SearchItem { id: string; - [key: string]: unknown; + title?: string; + subtitle?: string; } // State diff --git a/apps/calendar/apps/web/src/routes/(app)/settings/+page.svelte b/apps/calendar/apps/web/src/routes/(app)/settings/+page.svelte index d270cea1c..f8aab5bec 100644 --- a/apps/calendar/apps/web/src/routes/(app)/settings/+page.svelte +++ b/apps/calendar/apps/web/src/routes/(app)/settings/+page.svelte @@ -128,13 +128,19 @@ // View labels const viewLabels: Record = { day: 'Tag', + '3day': '3 Tage', '5day': '5 Tage', week: 'Woche', '10day': '10 Tage', '14day': '14 Tage', + '30day': '30 Tage', + '60day': '60 Tage', + '90day': '90 Tage', + '365day': '365 Tage', month: 'Monat', year: 'Jahr', agenda: 'Agenda', + custom: 'Benutzerdefiniert', }; // Duration options in minutes diff --git a/apps/calendar/apps/web/src/routes/(app)/statistics/+page.svelte b/apps/calendar/apps/web/src/routes/(app)/statistics/+page.svelte index 231dcd38c..bb74b211c 100644 --- a/apps/calendar/apps/web/src/routes/(app)/statistics/+page.svelte +++ b/apps/calendar/apps/web/src/routes/(app)/statistics/+page.svelte @@ -19,6 +19,7 @@ Clock, CalendarCheck, Hourglass, + type Icon as LucideIcon, } from 'lucide-svelte'; import { subDays, addDays } from 'date-fns'; @@ -39,42 +40,42 @@ id: 'eventsToday', label: 'Heute', value: calendarStatisticsStore.eventsToday, - icon: CalendarDays, + icon: CalendarDays as any, variant: 'success', }, { id: 'eventsThisWeek', label: 'Diese Woche', value: calendarStatisticsStore.eventsThisWeek, - icon: Calendar, + icon: Calendar as any, variant: 'primary', }, { id: 'upcoming', label: 'Anstehend (7 Tage)', value: calendarStatisticsStore.upcomingEvents, - icon: CalendarCheck, + icon: CalendarCheck as any, variant: 'info', }, { id: 'busyHours', label: 'Stunden/Woche', value: `${calendarStatisticsStore.busyHoursThisWeek}h`, - icon: Clock, + icon: Clock as any, variant: 'neutral', }, { id: 'calendars', label: 'Kalender', value: calendarStatisticsStore.totalCalendars, - icon: Calendar, + icon: Calendar as any, variant: 'accent', }, { id: 'avgDuration', label: 'Ø Dauer (Min)', value: calendarStatisticsStore.averageEventDuration, - icon: Hourglass, + icon: Hourglass as any, variant: 'info', }, ]); diff --git a/apps/chat/apps/web/src/lib/components/chat/ConversationList.svelte b/apps/chat/apps/web/src/lib/components/chat/ConversationList.svelte index 26e10c394..83b038d2a 100644 --- a/apps/chat/apps/web/src/lib/components/chat/ConversationList.svelte +++ b/apps/chat/apps/web/src/lib/components/chat/ConversationList.svelte @@ -107,6 +107,7 @@ {#if editingId === conv.id}
+
- -
+ Farbe +
{#each TEMPLATE_COLORS as color} + +
diff --git a/apps/chat/apps/web/src/routes/(protected)/templates/+page.svelte b/apps/chat/apps/web/src/routes/(protected)/templates/+page.svelte index deaf8eafa..5a991d86c 100644 --- a/apps/chat/apps/web/src/routes/(protected)/templates/+page.svelte +++ b/apps/chat/apps/web/src/routes/(protected)/templates/+page.svelte @@ -81,11 +81,11 @@ await templatesStore.createTemplate({ userId: authStore.user.id, name: data.name!, - description: data.description ?? null, + description: data.description, systemPrompt: data.systemPrompt!, - initialQuestion: data.initialQuestion ?? null, + initialQuestion: data.initialQuestion, color: data.color!, - modelId: data.modelId ?? null, + modelId: data.modelId, isDefault: false, documentMode: data.documentMode ?? false, }); diff --git a/apps/chat/packages/chat-types/src/index.ts b/apps/chat/packages/chat-types/src/index.ts index fec5145e5..7acfb5c86 100644 --- a/apps/chat/packages/chat-types/src/index.ts +++ b/apps/chat/packages/chat-types/src/index.ts @@ -71,10 +71,10 @@ export interface Template { id: string; userId: string; name: string; - description: string | null; + description?: string; systemPrompt: string; - initialQuestion: string | null; - modelId: string | null; + initialQuestion?: string; + modelId?: string; color: string; isDefault: boolean; documentMode: boolean; diff --git a/apps/clock/apps/web/src/lib/api/feedback.ts b/apps/clock/apps/web/src/lib/api/feedback.ts new file mode 100644 index 000000000..10e8a5dda --- /dev/null +++ b/apps/clock/apps/web/src/lib/api/feedback.ts @@ -0,0 +1,23 @@ +/** + * Feedback Service Instance for Clock Web App + */ + +import { createFeedbackService } from '@manacore/shared-feedback-service'; +import { authStore } from '$lib/stores/auth.svelte'; +import { browser } from '$app/environment'; + +// Get auth URL dynamically at runtime +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + return injectedUrl || 'http://localhost:3001'; + } + return 'http://localhost:3001'; +} + +export const feedbackService = createFeedbackService({ + apiUrl: getAuthUrl(), + appId: 'clock', + getAuthToken: async () => authStore.getAccessToken(), +}); diff --git a/apps/clock/apps/web/src/lib/components/life-clock/CircularProgress.svelte b/apps/clock/apps/web/src/lib/components/life-clock/CircularProgress.svelte index 8327c6928..d2318567c 100644 --- a/apps/clock/apps/web/src/lib/components/life-clock/CircularProgress.svelte +++ b/apps/clock/apps/web/src/lib/components/life-clock/CircularProgress.svelte @@ -20,7 +20,8 @@ let circumference = $derived(2 * Math.PI * radius); let dashOffset = $derived(circumference - (percentage / 100) * circumference); - // Animation + // Animation - intentionally captures initial circumference for animation start + // svelte-ignore state_referenced_locally let animatedOffset = $state(circumference); let mounted = $state(false); diff --git a/apps/clock/apps/web/src/routes/(app)/+layout.svelte b/apps/clock/apps/web/src/routes/(app)/+layout.svelte index d58c91855..6dffac47f 100644 --- a/apps/clock/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/clock/apps/web/src/routes/(app)/+layout.svelte @@ -69,7 +69,8 @@ try { // Search alarms - const alarms = await alarmsApi.getAll(); + const alarmsResponse = await alarmsApi.getAll(); + const alarms = alarmsResponse.data || []; const matchingAlarms = alarms .filter((alarm) => alarm.label?.toLowerCase().includes(queryLower)) .slice(0, 5) @@ -81,7 +82,8 @@ results.push(...matchingAlarms); // Search timers - const timers = await timersApi.getAll(); + const timersResponse = await timersApi.getAll(); + const timers = timersResponse.data || []; const matchingTimers = timers .filter((timer) => timer.label?.toLowerCase().includes(queryLower)) .slice(0, 5) diff --git a/apps/clock/apps/web/src/routes/(app)/alarms/+page.svelte b/apps/clock/apps/web/src/routes/(app)/alarms/+page.svelte index 16352dabc..ea3b454f4 100644 --- a/apps/clock/apps/web/src/routes/(app)/alarms/+page.svelte +++ b/apps/clock/apps/web/src/routes/(app)/alarms/+page.svelte @@ -265,25 +265,25 @@ }} > -
- +
+ -
- +
+
- +
{$_('alarm.repeat')}
{#each dayNames as day, i}
{#if editingLabelId === focused.id} + stopwatchesStore.delete(focused.id)} + aria-label="Delete stopwatch" > {def.icon}

{def.label}

-

{def.description}

+

{def.emoji}

{#if theme.variant === variant} diff --git a/apps/clock/apps/web/src/routes/(app)/timers/+page.svelte b/apps/clock/apps/web/src/routes/(app)/timers/+page.svelte index 36b3d05a5..6c4284989 100644 --- a/apps/clock/apps/web/src/routes/(app)/timers/+page.svelte +++ b/apps/clock/apps/web/src/routes/(app)/timers/+page.svelte @@ -245,6 +245,7 @@ e.stopPropagation(); handleDelete(timer.id, isLocal); }} + aria-label="Delete timer" > removeCity(clock.id)} + aria-label="Remove city" >

{$_('worldClock.add')}

-