diff --git a/apps/webui/src/app/dashboard/[guildId]/layout.tsx b/apps/webui/src/app/dashboard/[guildId]/layout.tsx
index ade1c86..9cb93fe 100644
--- a/apps/webui/src/app/dashboard/[guildId]/layout.tsx
+++ b/apps/webui/src/app/dashboard/[guildId]/layout.tsx
@@ -2,7 +2,7 @@ import { notFound } from 'next/navigation';
import type { ReactNode } from 'react';
import { DashboardShell } from '@/components/layout/dashboard-shell';
import { requireGuildAccessOrRedirect } from '@/lib/auth';
-import { getManageableGuilds } from '@/lib/guilds';
+import { getManageableGuilds, resolveDashboardGuild } from '@/lib/guilds';
import { isOwnerUser } from '@/lib/owner-auth';
interface GuildLayoutProps {
@@ -13,23 +13,26 @@ interface GuildLayoutProps {
export default async function GuildLayout({ children, params }: GuildLayoutProps) {
const { guildId } = await params;
const session = await requireGuildAccessOrRedirect(guildId);
- const guilds = await getManageableGuilds(session);
- const currentGuild = guilds.find((guild) => guild.id === guildId);
+ const [resolved, guilds, showOwnerLink] = await Promise.all([
+ resolveDashboardGuild(session, guildId),
+ getManageableGuilds(session),
+ isOwnerUser(session.user.id)
+ ]);
- if (!currentGuild) {
+ if (!resolved) {
notFound();
}
const otherGuilds = guilds.filter((guild) => guild.id !== guildId);
- const showOwnerLink = await isOwnerUser(session.user.id);
return (
{children}
diff --git a/apps/webui/src/app/dashboard/[guildId]/welcome/page.tsx b/apps/webui/src/app/dashboard/[guildId]/welcome/page.tsx
index 4c7adc7..f0a4d1e 100644
--- a/apps/webui/src/app/dashboard/[guildId]/welcome/page.tsx
+++ b/apps/webui/src/app/dashboard/[guildId]/welcome/page.tsx
@@ -1,7 +1,7 @@
import { notFound } from 'next/navigation';
import { WelcomeForm } from '@/components/modules/welcome-form';
import { requireGuildAccessOrRedirect } from '@/lib/auth';
-import { getManageableGuild } from '@/lib/guilds';
+import { resolveDashboardGuild } from '@/lib/guilds';
import { getLocale, t } from '@/lib/i18n';
import { getWelcomeDashboard } from '@/lib/module-configs/welcome';
import { buildWelcomePreviewVars } from '@/lib/welcome-preview-vars';
@@ -13,13 +13,13 @@ interface WelcomePageProps {
export default async function WelcomePage({ params }: WelcomePageProps) {
const { guildId } = await params;
const session = await requireGuildAccessOrRedirect(guildId);
- const [locale, config, guild] = await Promise.all([
+ const [locale, config, resolved] = await Promise.all([
getLocale(),
getWelcomeDashboard(guildId),
- getManageableGuild(session, guildId)
+ resolveDashboardGuild(session, guildId)
]);
- if (!guild) {
+ if (!resolved) {
notFound();
}
@@ -32,7 +32,7 @@ export default async function WelcomePage({ params }: WelcomePageProps) {
);
diff --git a/apps/webui/src/components/layout/dashboard-shell.tsx b/apps/webui/src/components/layout/dashboard-shell.tsx
index 904d83c..031b6db 100644
--- a/apps/webui/src/components/layout/dashboard-shell.tsx
+++ b/apps/webui/src/components/layout/dashboard-shell.tsx
@@ -18,6 +18,8 @@ interface DashboardShellProps {
otherGuilds: DashboardGuild[];
user: SessionUser;
showOwnerLink?: boolean;
+ /** True when an Owner-panel user opened a guild they do not manage on Discord. */
+ ownerBypass?: boolean;
children: ReactNode;
}
@@ -27,6 +29,7 @@ export function DashboardShell({
otherGuilds,
user,
showOwnerLink = false,
+ ownerBypass = false,
children
}: DashboardShellProps) {
const t = useTranslations();
@@ -59,7 +62,21 @@ export function DashboardShell({
- {children}
+
+ {ownerBypass ? (
+
+ ) : null}
+ {children}
+
diff --git a/apps/webui/src/components/owner/owner-forms.tsx b/apps/webui/src/components/owner/owner-forms.tsx
index 97bb51d..058613d 100644
--- a/apps/webui/src/components/owner/owner-forms.tsx
+++ b/apps/webui/src/components/owner/owner-forms.tsx
@@ -1,5 +1,6 @@
'use client';
+import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useMemo, useState, useTransition } from 'react';
import { toast } from 'sonner';
@@ -165,6 +166,9 @@ export function GuildsManager({
+