feat: auto-redirect to Pro shell when proInterface is on

This commit is contained in:
Linus Rath
2026-05-21 15:47:05 +02:00
parent 9763ffa2a3
commit b75bbaa517
4 changed files with 52 additions and 19 deletions
+38
View File
@@ -0,0 +1,38 @@
"use client";
import { useEffect } from "react";
import { usePathname, useRouter } from "@/i18n/navigation";
import { useSettingsStore } from "@/stores/settings-store";
import { useIsDesktop } from "@/hooks/use-media-query";
import { useProTabStore, type ProTabKind } from "@/stores/pro-tab-store";
const STANDARD_PATH_TO_TAB: Record<string, Exclude<ProTabKind, 'compose' | 'email'>> = {
'/': 'mail',
'/calendar': 'calendar',
'/contacts': 'contacts',
'/files': 'files',
'/settings': 'settings',
};
/**
* When the Pro interface is enabled, the standard mail/calendar/contacts/
* files/settings routes are taken over by the Pro shell — the user shouldn't
* have to click "Open" in settings to land there. Mobile/tablet keeps the
* standard layout because Pro is desktop-only (see pro/page.tsx).
*/
export function ProInterfaceRedirect() {
const router = useRouter();
const pathname = usePathname();
const proInterface = useSettingsStore((s) => s.proInterface);
const isDesktop = useIsDesktop();
useEffect(() => {
if (!proInterface || !isDesktop) return;
const tabKind = STANDARD_PATH_TO_TAB[pathname];
if (!tabKind) return;
useProTabStore.getState().openTab(tabKind);
router.replace('/pro');
}, [proInterface, isDesktop, pathname, router]);
return null;
}
+4 -17
View File
@@ -1,13 +1,11 @@
"use client";
import { useTranslations } from 'next-intl';
import { Link } from '@/i18n/navigation';
import { useSettingsStore, type ToolbarPosition, type MailLayout } from '@/stores/settings-store';
import { SettingsSection, SettingItem, RadioGroup, ToggleSwitch } from './settings-section';
import { cn } from '@/lib/utils';
import { usePolicyStore } from '@/stores/policy-store';
import { useAccountStore } from '@/stores/account-store';
import { useMediaQuery } from '@/hooks/use-media-query';
const MAIL_LAYOUT_PREVIEW_ROWS = [
{ sender: 'Alice', subject: 'Quarterly roadmap', preview: 'The draft is ready for review.', selected: false },
@@ -120,7 +118,6 @@ export function LayoutSettings() {
const { toolbarPosition, showToolbarLabels, hideAccountSwitcher, showRailAccountList, enableUnifiedMailbox, colorfulSidebarIcons, mailLayout, proInterface, updateSetting } = useSettingsStore();
const { isSettingLocked, isSettingHidden } = usePolicyStore();
const accounts = useAccountStore(s => s.accounts);
const isDesktop = useMediaQuery('(min-width: 1024px)');
return (
<SettingsSection title={t('title')} description={t('description')}>
@@ -193,20 +190,10 @@ export function LayoutSettings() {
)}
<SettingItem label={t('pro_interface.label')} description={t('pro_interface.description')}>
<div className="flex items-center gap-3">
{proInterface && isDesktop && (
<Link
href="/pro"
className="text-sm font-medium text-primary hover:underline"
>
{t('pro_interface.open_label')}
</Link>
)}
<ToggleSwitch
checked={proInterface}
onChange={(v) => updateSetting('proInterface', v)}
/>
</div>
<ToggleSwitch
checked={proInterface}
onChange={(v) => updateSetting('proInterface', v)}
/>
</SettingItem>
</SettingsSection>
);