diff --git a/apps/mana/apps/web/src/lib/components/feedback/GlobalFeedbackPill.svelte b/apps/mana/apps/web/src/lib/components/feedback/GlobalFeedbackPill.svelte deleted file mode 100644 index 8ca05aa22..000000000 --- a/apps/mana/apps/web/src/lib/components/feedback/GlobalFeedbackPill.svelte +++ /dev/null @@ -1,100 +0,0 @@ - - - -{#if !hidden} - - - (open = false)} /> -{/if} - - diff --git a/apps/mana/apps/web/src/routes/(app)/+layout.svelte b/apps/mana/apps/web/src/routes/(app)/+layout.svelte index e1e5a80e5..f11925b88 100644 --- a/apps/mana/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/mana/apps/web/src/routes/(app)/+layout.svelte @@ -9,7 +9,7 @@ import { page } from '$app/stores'; import type { Component, Snippet } from 'svelte'; import ToastContainer from '$lib/components/ToastContainer.svelte'; - import GlobalFeedbackPill from '$lib/components/feedback/GlobalFeedbackPill.svelte'; + import FeedbackQuickModal from '$lib/components/feedback/FeedbackQuickModal.svelte'; import { onDestroy, setContext, tick } from 'svelte'; import { createReminderScheduler } from '@mana/shared-stores'; import { todoReminderSource } from '$lib/modules/todo/reminder-source'; @@ -251,6 +251,17 @@ let isBottomBarVisible = $state(false); let activeBar = $state(null); + // Quick-feedback modal — opened from the user-menu chip ("Idee teilen"). + // Replaces the older floating "Idee?" pill so feedback lives in the same + // affordance as Profile / Credits / Logout. + let feedbackModalOpen = $state(false); + let feedbackModuleContext = $derived.by(() => { + const path = $page.url.pathname; + const seg = path.split('/').filter(Boolean)[0]; + const fromPath = seg && !seg.startsWith('(') ? seg : null; + return $page.url.searchParams.get('app') ?? fromPath ?? undefined; + }); + function closeAllBars() { isTagStripVisible = false; isQuickInputVisible = false; @@ -1061,6 +1072,7 @@ creditsHref="/?app=credits" themesHref="/?app=themes" helpHref="/?app=help" + onFeedback={() => (feedbackModalOpen = true)} {spotlightActions} {contentSearcher} positioning="static" @@ -1139,9 +1151,12 @@ /> {/if} - - + + (feedbackModalOpen = false)} + /> diff --git a/packages/shared-ui/src/navigation/PillNavigation.svelte b/packages/shared-ui/src/navigation/PillNavigation.svelte index 66980e69d..3db57a988 100644 --- a/packages/shared-ui/src/navigation/PillNavigation.svelte +++ b/packages/shared-ui/src/navigation/PillNavigation.svelte @@ -52,6 +52,7 @@ Heart, House, Key, + Lightbulb, List, MagnifyingGlass, Microphone, @@ -135,6 +136,7 @@ scale: Scales, robot: Robot, key: Key, + lightbulb: Lightbulb, shield: Shield, gift: Gift, 'music-notes': MusicNotes, @@ -318,8 +320,13 @@ contentSearcher?: ContentSearcher; /** Accessible label for the nav element */ ariaLabel?: string; - /** Feedback page href (shown in user dropdown). Set to empty string to hide. */ + /** Feedback page href (shown in user dropdown). Set to empty string to hide. + * Ignored when `onFeedback` is provided — the action takes precedence. */ feedbackHref?: string; + /** Called when the user picks "Idee teilen" in the user menu. When set, + * the Feedback chip opens the host's quick-feedback modal instead of + * navigating to feedbackHref. */ + onFeedback?: () => void; /** Themes page href (shown in user dropdown). Set to empty string to hide. */ themesHref?: string; /** Spiral page href (shown in user dropdown). Set to empty string to hide. */ @@ -391,6 +398,7 @@ contentSearcher, ariaLabel, feedbackHref = '/feedback', + onFeedback, themesHref, spiralHref, creditsHref, @@ -461,7 +469,14 @@ // Account links for UserMenuPanel const accountLinks = $derived.by(() => { - const links: { id: string; label: string; icon: string; href: string; active?: boolean }[] = []; + const links: { + id: string; + label: string; + icon: string; + href?: string; + onClick?: () => void; + active?: boolean; + }[] = []; if (userEmail && profileHref) { links.push({ id: 'profile', @@ -489,7 +504,14 @@ active: currentPath === creditsHref, }); } - if (userEmail && feedbackHref) { + if (userEmail && onFeedback) { + links.push({ + id: 'feedback', + label: 'Idee teilen', + icon: 'lightbulb', + onClick: onFeedback, + }); + } else if (userEmail && feedbackHref) { links.push({ id: 'feedback', label: 'Feedback', @@ -533,6 +555,15 @@ // we don't duplicate it inside the opened bar. const userMenuBarItems = $derived.by(() => { const out: PillDropdownItem[] = []; + if (userEmail && onFeedback) { + out.push({ + id: 'feedback', + label: 'Idee teilen', + icon: 'lightbulb', + onClick: () => onFeedback(), + }); + out.push({ id: 'feedback-divider', label: '', divider: true }); + } if (onThemeModeChange) { out.push( { diff --git a/packages/shared-ui/src/navigation/UserMenuPanel.svelte b/packages/shared-ui/src/navigation/UserMenuPanel.svelte index 8986f6df4..73a9ae9e3 100644 --- a/packages/shared-ui/src/navigation/UserMenuPanel.svelte +++ b/packages/shared-ui/src/navigation/UserMenuPanel.svelte @@ -8,6 +8,7 @@ Gear, Globe, Heart, + Lightbulb, Moon, Palette, Question, @@ -36,6 +37,7 @@ sun: Sun, palette: Palette, robot: Robot, + lightbulb: Lightbulb, logout: SignOut, }; @@ -43,7 +45,8 @@ id: string; label: string; icon: string; - href: string; + href?: string; + onClick?: () => void; active?: boolean; } @@ -182,7 +185,14 @@