Add settings layout and page structure for authenticated routes

Introduce tabbed navigation for the settings page, including Profile, Password, Sessions, and Preferences sections. Add placeholders for each section with metadata and routes. Redirect `/settings` to `/settings/profile`. Integrate `AuthGuard` for settings and authenticated layouts while incorporating reusable `Header` and `Footer` components.
This commit is contained in:
2025-11-02 05:59:20 +01:00
parent bf04c98408
commit 4536c607eb
7 changed files with 224 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
/**
* Authenticated Route Group Layout
* Wraps all authenticated routes with AuthGuard and provides common layout structure
*/
import type { Metadata } from 'next';
import { AuthGuard } from '@/components/auth';
import { Header } from '@/components/layout/Header';
import { Footer } from '@/components/layout/Footer';
export const metadata: Metadata = {
title: {
template: '%s | FastNext Template',
default: 'Dashboard',
},
};
export default function AuthenticatedLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<AuthGuard>
<div className="flex min-h-screen flex-col">
<Header />
<main className="flex-1">
{children}
</main>
<Footer />
</div>
</AuthGuard>
);
}

View File

@@ -0,0 +1,88 @@
/**
* Settings Layout
* Provides tabbed navigation for settings pages
*/
'use client';
import { usePathname } from 'next/navigation';
import Link from 'next/link';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { User, Lock, Monitor, Settings as SettingsIcon } from 'lucide-react';
/**
* Settings tabs configuration
*/
const settingsTabs = [
{
value: 'profile',
label: 'Profile',
href: '/settings/profile',
icon: User,
},
{
value: 'password',
label: 'Password',
href: '/settings/password',
icon: Lock,
},
{
value: 'sessions',
label: 'Sessions',
href: '/settings/sessions',
icon: Monitor,
},
{
value: 'preferences',
label: 'Preferences',
href: '/settings/preferences',
icon: SettingsIcon,
},
];
export default function SettingsLayout({
children,
}: {
children: React.ReactNode;
}) {
const pathname = usePathname();
// Determine active tab based on pathname
const activeTab = settingsTabs.find((tab) => pathname.startsWith(tab.href))?.value || 'profile';
return (
<div className="container mx-auto px-4 py-8">
{/* Page Header */}
<div className="mb-8">
<h1 className="text-3xl font-bold text-gray-900 dark:text-white">
Settings
</h1>
<p className="mt-2 text-gray-600 dark:text-gray-400">
Manage your account settings and preferences
</p>
</div>
{/* Tabs Navigation */}
<Tabs value={activeTab} className="space-y-6">
<TabsList className="grid w-full grid-cols-2 md:grid-cols-4 lg:w-[600px]">
{settingsTabs.map((tab) => {
const Icon = tab.icon;
return (
<TabsTrigger key={tab.value} value={tab.value} asChild>
<Link href={tab.href} className="flex items-center space-x-2">
<Icon className="h-4 w-4" />
<span>{tab.label}</span>
</Link>
</TabsTrigger>
);
})}
</TabsList>
{/* Tab Content */}
<div className="rounded-lg border bg-white dark:bg-gray-900 p-6">
{children}
</div>
</Tabs>
</div>
);
}

View File

@@ -0,0 +1,10 @@
/**
* Settings Index Page
* Redirects to /settings/profile
*/
import { redirect } from 'next/navigation';
export default function SettingsPage() {
redirect('/settings/profile');
}

View File

@@ -0,0 +1,23 @@
/**
* Password Settings Page
* Change password functionality
*/
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Password Settings',
};
export default function PasswordSettingsPage() {
return (
<div>
<h2 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">
Password Settings
</h2>
<p className="text-gray-600 dark:text-gray-400">
Change your password (Coming in Task 3.3)
</p>
</div>
);
}

View File

@@ -0,0 +1,23 @@
/**
* User Preferences Page
* Theme, notifications, and other preferences
*/
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Preferences',
};
export default function PreferencesPage() {
return (
<div>
<h2 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">
Preferences
</h2>
<p className="text-gray-600 dark:text-gray-400">
Configure your preferences (Coming in Task 3.5)
</p>
</div>
);
}

View File

@@ -0,0 +1,23 @@
/**
* Profile Settings Page
* User profile management - edit name, email, phone, preferences
*/
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Profile Settings',
};
export default function ProfileSettingsPage() {
return (
<div>
<h2 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">
Profile Settings
</h2>
<p className="text-gray-600 dark:text-gray-400">
Manage your profile information (Coming in Task 3.2)
</p>
</div>
);
}

View File

@@ -0,0 +1,23 @@
/**
* Session Management Page
* View and manage active sessions across devices
*/
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Active Sessions',
};
export default function SessionsPage() {
return (
<div>
<h2 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">
Active Sessions
</h2>
<p className="text-gray-600 dark:text-gray-400">
Manage your active sessions (Coming in Task 3.4)
</p>
</div>
);
}