wulf-pulse/app/mobile/profile/page.tsx
lorentz 1b7c453c6d feat(09-05): ProfileChannelsSection (Teams + ntfy + QR code) + qrcode.react install
- Create ProfileChannelsSection.tsx with Teams + ntfy sub-sections
- Teams: URL input, inline 400 error (teamsError), save/clear buttons, inline test result
- ntfy: mint-on-first-save (State A → State B), QR code via QRCodeSVG, subscribe link
- ntfy: advanced disclosure with custom topic input + inline 400 error (customTopicError)
- ntfy: test-now and remove buttons
- Install qrcode.react ^4.2.0 (node_modules + package.json + package-lock.json updated)
- Delete ProfileChannelsSectionPlaceholder.tsx (replaced by real component)
- Update app/mobile/profile/page.tsx import to ProfileChannelsSection (not Placeholder)
2026-05-10 07:48:03 -04:00

30 lines
1.3 KiB
TypeScript

// /mobile/profile (PROF-01) — gated by requireAuth(), server-rendered shell
// hosts the four client sections.
import { redirect } from 'next/navigation';
import { requireAuth } from '@/lib/auth-utils';
import { ProfileTimezoneSection } from '@/components/mobile/profile/ProfileTimezoneSection';
import { ProfileThemeSection } from '@/components/mobile/profile/ProfileThemeSection';
import { ProfileNotificationMatrix } from '@/components/mobile/profile/ProfileNotificationMatrix';
import { ProfileChannelsSection } from '@/components/mobile/profile/ProfileChannelsSection';
export default async function MobileProfilePage() {
const { session, error } = await requireAuth();
// CRITICAL: requireAuth() returns NextResponse on miss — that shape is for
// API routes only. A Page route MUST call redirect() instead. Returning
// `error` from here would render a JSON 401 body as the page, which is wrong.
if (error || !session) {
redirect('/auth/sign-in');
}
return (
<main className="px-4 pb-safe">
<h1 className="text-xl font-semibold pt-4 pb-2">Profile &amp; Preferences</h1>
<div className="space-y-4">
<ProfileTimezoneSection />
<ProfileThemeSection />
<ProfileNotificationMatrix />
<ProfileChannelsSection />
</div>
</main>
);
}