From a44f1dc384c0e73e615739320e1be2f64a9d65c1 Mon Sep 17 00:00:00 2001 From: Creeperkatze <178587183+Creeperkatze@users.noreply.github.com> Date: Mon, 2 Feb 2026 01:14:41 +0100 Subject: [PATCH 01/32] Add notifications icon --- apps/frontend/src/layouts/default.vue | 47 +++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/apps/frontend/src/layouts/default.vue b/apps/frontend/src/layouts/default.vue index d9451cc468..9f42c909b9 100644 --- a/apps/frontend/src/layouts/default.vue +++ b/apps/frontend/src/layouts/default.vue @@ -423,6 +423,27 @@ + + + + { return useBaseFetch('payout/balance', { apiVersion: 3 }) }) +const { data: notificationsData, refresh: refreshNotifications } = await useAsyncData( + 'header-notifications', + async () => { + if (!auth.value.user) return null + + // TODO: Remove mock data + const mockNotifications = [ + { id: '1', read: false, type: 'project_update' }, + { id: '2', read: false, type: 'project_update' }, + { id: '3', read: true, type: 'project_update' }, + ] + + return mockNotifications + + // return useBaseFetch(`user/${auth.value.user.id}/notifications`) + }, + { + watch: [auth], + }, +) + +const unreadNotificationsCount = computed(() => { + if (!notificationsData.value) return 0 + return notificationsData.value.filter((n) => !n.read).length +}) + const showTaxComplianceBanner = computed(() => { if (flags.value.testTaxForm && auth.value.user) return true const bal = payoutBalance.value From dab79b842b00619b69f7282ceb9ea9040229b05c Mon Sep 17 00:00:00 2001 From: Creeperkatze <178587183+Creeperkatze@users.noreply.github.com> Date: Mon, 2 Feb 2026 02:49:18 +0100 Subject: [PATCH 02/32] Add popout --- .../src/helpers/platform-notifications.ts | 61 +++++++ apps/frontend/src/layouts/default.vue | 171 +++++++++++++++--- 2 files changed, 208 insertions(+), 24 deletions(-) diff --git a/apps/frontend/src/helpers/platform-notifications.ts b/apps/frontend/src/helpers/platform-notifications.ts index e151d583a5..bc961a993b 100644 --- a/apps/frontend/src/helpers/platform-notifications.ts +++ b/apps/frontend/src/helpers/platform-notifications.ts @@ -2,6 +2,67 @@ import type { Organization, Project, Report, User, Version } from '@modrinth/uti type Thread = { id: string } +// TODO: Remove mock data when API is ready +export const mockNotifications: PlatformNotification[] = [ + { + id: '1', + user_id: 'mock-user-id', + type: 'project_update', + title: 'New project created', + text: 'Your project was successfully created', + link: '/project/test-project', + read: false, + created: new Date().toISOString(), + actions: [], + body: { project_id: 'mock-project-id' }, + extra_data: { + project: { + slug: 'test-project', + icon_url: + 'https://cdn.modrinth.com/data/AANobbMI/295862f4724dc3f78df3447ad6072b2dcd3ef0c9_96.webp', + }, + }, + }, + { + id: '2', + user_id: 'mock-user-id', + type: 'team_invite', + title: 'Invited to join team', + text: 'You have been invited to join a project team', + link: '/project/invited-project', + read: false, + created: new Date().toISOString(), + actions: [], + body: { team_id: 'test-team-id', project_id: 'invited-project-id' }, + extra_data: { + project: { + slug: 'invited-project', + icon_url: + 'https://cdn.modrinth.com/data/AANobbMI/295862f4724dc3f78df3447ad6072b2dcd3ef0c9_96.webp', + }, + }, + }, + { + id: '3', + user_id: 'mock-user-id', + type: 'organization_invite', + title: 'Organization invitation', + text: 'You have been invited to join an organization', + link: '/organization/test-org', + read: false, + created: new Date().toISOString(), + actions: [], + body: { organization_id: 'test-org-id', invited_by: 'inviter-id' }, + extra_data: { + organization: { + slug: 'test-org', + icon_url: + 'https://cdn.modrinth.com/data/AANobbMI/295862f4724dc3f78df3447ad6072b2dcd3ef0c9_96.webp', + }, + }, + }, +] + export type PlatformNotificationAction = { title: string action_route: [string, string] diff --git a/apps/frontend/src/layouts/default.vue b/apps/frontend/src/layouts/default.vue index 9f42c909b9..80b5cd9ace 100644 --- a/apps/frontend/src/layouts/default.vue +++ b/apps/frontend/src/layouts/default.vue @@ -424,25 +424,93 @@ - -