diff --git a/apps/mana/apps/web/src/lib/api/config.ts b/apps/mana/apps/web/src/lib/api/config.ts index 68c81b83a..ef579bd6e 100644 --- a/apps/mana/apps/web/src/lib/api/config.ts +++ b/apps/mana/apps/web/src/lib/api/config.ts @@ -22,6 +22,19 @@ export function getManaAuthUrl(): string { return process.env.PUBLIC_MANA_AUTH_URL || 'http://localhost:3001'; } +/** + * Get the mana-analytics service URL (port 3064 in dev). + * Hosts the public-community feedback hub. + */ +export function getManaAnalyticsUrl(): string { + if (browser && typeof window !== 'undefined') { + const injected = (window as unknown as { __PUBLIC_MANA_ANALYTICS_URL__?: string }) + .__PUBLIC_MANA_ANALYTICS_URL__; + return injected || 'http://localhost:3064'; + } + return process.env.PUBLIC_MANA_ANALYTICS_URL || 'http://localhost:3064'; +} + /** * Get the mana-events service URL (Phase 1b: public RSVP backend). */ diff --git a/apps/mana/apps/web/src/lib/api/feedback.ts b/apps/mana/apps/web/src/lib/api/feedback.ts index e07a31da7..c73676cdd 100644 --- a/apps/mana/apps/web/src/lib/api/feedback.ts +++ b/apps/mana/apps/web/src/lib/api/feedback.ts @@ -1,13 +1,22 @@ /** - * Feedback Service Instance for Mana Web App + * Feedback Service Instance for Mana Web App. + * + * Talks to mana-analytics (port 3064 in dev). Two factories: + * - feedbackService: auth-required for submit/react/admin + * - publicFeedbackService: anonymous read-only for SSR + non-logged-in */ -import { createFeedbackService } from '@mana/feedback'; +import { createFeedbackService, createPublicFeedbackService } from '@mana/feedback'; import { authStore } from '$lib/stores/auth.svelte'; -import { getManaAuthUrl } from './config'; +import { getManaAnalyticsUrl } from './config'; export const feedbackService = createFeedbackService({ - apiUrl: getManaAuthUrl(), + apiUrl: getManaAnalyticsUrl(), appId: 'mana', getAuthToken: async () => authStore.getValidToken(), }); + +export const publicFeedbackService = createPublicFeedbackService({ + apiUrl: getManaAnalyticsUrl(), + appId: 'mana', +}); diff --git a/apps/mana/apps/web/src/lib/app-registry/apps.ts b/apps/mana/apps/web/src/lib/app-registry/apps.ts index 0dc54ef02..7aa4fc18a 100644 --- a/apps/mana/apps/web/src/lib/app-registry/apps.ts +++ b/apps/mana/apps/web/src/lib/app-registry/apps.ts @@ -83,6 +83,7 @@ import { NotePencil, FilmStrip, Hourglass, + Megaphone, } from '@mana/shared-icons'; // ── Apps with entity capabilities ─────────────────────────── @@ -1332,6 +1333,16 @@ registerApp({ }, }); +registerApp({ + id: 'community', + name: 'Community', + color: '#F59E0B', + icon: Megaphone, + views: { + list: { load: () => import('$lib/modules/community/ListView.svelte') }, + }, +}); + registerApp({ id: 'wardrobe', name: 'Kleiderschrank', diff --git a/apps/mana/apps/web/src/lib/components/feedback/FeedbackHook.svelte b/apps/mana/apps/web/src/lib/components/feedback/FeedbackHook.svelte new file mode 100644 index 000000000..6215cc77c --- /dev/null +++ b/apps/mana/apps/web/src/lib/components/feedback/FeedbackHook.svelte @@ -0,0 +1,65 @@ + + + +{#if authStore.user} + + + (open = false)} /> +{/if} + + diff --git a/apps/mana/apps/web/src/lib/components/feedback/FeedbackQuickModal.svelte b/apps/mana/apps/web/src/lib/components/feedback/FeedbackQuickModal.svelte new file mode 100644 index 000000000..f7534c4e7 --- /dev/null +++ b/apps/mana/apps/web/src/lib/components/feedback/FeedbackQuickModal.svelte @@ -0,0 +1,395 @@ + + + +{#if open} + + + +{/if} + + diff --git a/apps/mana/apps/web/src/lib/components/feedback/GlobalFeedbackPill.svelte b/apps/mana/apps/web/src/lib/components/feedback/GlobalFeedbackPill.svelte new file mode 100644 index 000000000..8ca05aa22 --- /dev/null +++ b/apps/mana/apps/web/src/lib/components/feedback/GlobalFeedbackPill.svelte @@ -0,0 +1,100 @@ + + + +{#if !hidden} + + + (open = false)} /> +{/if} + + diff --git a/apps/mana/apps/web/src/lib/components/shell/ModuleShell.svelte b/apps/mana/apps/web/src/lib/components/shell/ModuleShell.svelte index 958a3a426..170408de9 100644 --- a/apps/mana/apps/web/src/lib/components/shell/ModuleShell.svelte +++ b/apps/mana/apps/web/src/lib/components/shell/ModuleShell.svelte @@ -34,6 +34,7 @@ } from '@mana/shared-icons'; import type { Snippet, Component } from 'svelte'; import { PAGE_WIDTH_PRESETS, nearestPresetIndex } from '../page-carousel/width-presets'; + import FeedbackHook from '$lib/components/feedback/FeedbackHook.svelte'; interface Props { // Layout mode @@ -66,6 +67,15 @@ helpOpen?: boolean; onContextMenu?: (e: MouseEvent) => void; + // Inline feedback hook — renders a small Lightbulb button in the + // window-actions row. Submitted feedback is tagged with `moduleId` + // so the public community feed can group/filter by module. + /** Module identifier passed to the inline FeedbackHook. */ + moduleId?: string; + /** Suppress the auto-injected FeedbackHook (e.g. on the + * /community-/feedback-pages where it's redundant). */ + hideFeedback?: boolean; + // Snippets header_left?: Snippet; badge?: Snippet; @@ -94,6 +104,8 @@ onHelp, helpOpen = false, onContextMenu, + moduleId, + hideFeedback = false, header_left, badge, actions, @@ -192,6 +204,9 @@ {#if actions} {@render actions()} {/if} + {#if !hideFeedback} + + {/if} {#if onHelp}