Remove all obsolete authentication, settings, admin, and demo-related components and pages

- Eliminated redundant components, pages, and layouts related to authentication (`login`, `register`, `password-reset`, etc.), user settings, admin, and demos.
- Simplified the frontend structure by removing unused dynamic imports, forms, and test code.
- Refactored configurations and metadata imports to exclude references to removed features.
- Streamlined the project for future development and improved maintainability by discarding legacy and unused code.
This commit is contained in:
Felipe Cardoso
2025-11-18 12:41:57 +01:00
parent a73d3c7d3e
commit d1b47006f4
56 changed files with 259 additions and 208 deletions

View File

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

View File

@@ -5,11 +5,12 @@
'use client';
import { useSearchParams, useRouter } from 'next/navigation';
import { useSearchParams } from 'next/navigation';
import { useRouter } from '@/lib/i18n/routing';
import { useEffect, useRef } from 'react';
import dynamic from 'next/dynamic';
import { Alert } from '@/components/ui/alert';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
// Code-split PasswordResetConfirmForm (319 lines)
const PasswordResetConfirmForm = dynamic(

View File

@@ -5,8 +5,8 @@
'use client';
import { usePathname } from 'next/navigation';
import Link from 'next/link';
import { usePathname } from '@/lib/i18n/routing';
import { Link } from '@/lib/i18n/routing';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { User, Lock, Monitor, Settings as SettingsIcon } from 'lucide-react';

View File

@@ -0,0 +1,11 @@
/**
* Settings Index Page
* Redirects to /settings/profile
*/
import { redirect } from 'next/navigation';
export default async function SettingsPage({ params }: { params: Promise<{ locale: string }> }) {
const { locale } = await params;
redirect(`/${locale}/settings/profile`);
}

View File

@@ -6,7 +6,7 @@
/* istanbul ignore next - Next.js type import for metadata */
import type { Metadata } from 'next';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { ArrowLeft } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { OrganizationMembersContent } from '@/components/admin/organizations/OrganizationMembersContent';

View File

@@ -6,7 +6,7 @@
/* istanbul ignore next - Next.js type import for metadata */
import type { Metadata } from 'next';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { ArrowLeft } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { OrganizationManagementContent } from '@/components/admin/organizations/OrganizationManagementContent';

View File

@@ -6,7 +6,7 @@
/* istanbul ignore next - Next.js type import for metadata */
import type { Metadata } from 'next';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { DashboardStats } from '@/components/admin';
import {
UserGrowthChart,

View File

@@ -6,7 +6,7 @@
/* istanbul ignore next - Next.js type import for metadata */
import type { Metadata } from 'next';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { ArrowLeft } from 'lucide-react';
import { Button } from '@/components/ui/button';

View File

@@ -6,7 +6,7 @@
/* istanbul ignore next - Next.js type import for metadata */
import type { Metadata } from 'next';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { ArrowLeft } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { UserManagementContent } from '@/components/admin/users/UserManagementContent';

View File

@@ -4,7 +4,7 @@
*/
import type { Metadata } from 'next';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import {
Palette,
ShieldCheck,

View File

@@ -4,7 +4,7 @@
* Access: /dev/docs
*/
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import {
BookOpen,
Sparkles,

View File

@@ -7,7 +7,7 @@
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

View File

@@ -5,7 +5,7 @@
*/
import type { Metadata } from 'next';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { Grid3x3 } from 'lucide-react';
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
import { Button } from '@/components/ui/button';

View File

@@ -5,7 +5,7 @@
*/
import type { Metadata } from 'next';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { Palette, Layout, Ruler, FileText, BookOpen, ArrowRight, Sparkles } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';

View File

@@ -6,7 +6,7 @@
import type { Metadata } from 'next';
import dynamic from 'next/dynamic';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { Ruler } from 'lucide-react';
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
import { Button } from '@/components/ui/button';

View File

@@ -5,7 +5,7 @@
/* istanbul ignore next - Next.js type import for metadata */
import type { Metadata } from 'next';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { ShieldAlert } from 'lucide-react';
import { Button } from '@/components/ui/button';

View File

@@ -0,0 +1,88 @@
import type { Metadata } from 'next';
import { Geist, Geist_Mono } from 'next/font/google';
import { notFound } from 'next/navigation';
import { routing } from '@/lib/i18n/routing';
import { NextIntlClientProvider } from 'next-intl';
import { getMessages } from 'next-intl/server';
import '../globals.css';
import { Providers } from '../providers';
import { AuthProvider } from '@/lib/auth/AuthContext';
import { AuthInitializer } from '@/components/auth';
const geistSans = Geist({
variable: '--font-geist-sans',
subsets: ['latin'],
display: 'swap', // Prevent font from blocking render
preload: true,
});
const geistMono = Geist_Mono({
variable: '--font-geist-mono',
subsets: ['latin'],
display: 'swap', // Prevent font from blocking render
preload: false, // Only preload primary font
});
export const metadata: Metadata = {
title: 'FastNext Template',
description: 'FastAPI + Next.js Template',
};
export default async function LocaleLayout({
children,
params,
}: Readonly<{
children: React.ReactNode;
params: Promise<{ locale: string }>;
}>) {
// Await params in Next.js 15
const { locale } = await params;
// Ensure that the incoming `locale` is valid
if (!routing.locales.includes(locale as 'en' | 'it')) {
notFound();
}
// Providing all messages to the client
// side is the easiest way to get started
const messages = await getMessages();
return (
<html lang={locale} suppressHydrationWarning>
<head>
{/* Theme initialization script - runs before React hydrates to prevent FOUC */}
<script
dangerouslySetInnerHTML={{
__html: `
(function() {
try {
const theme = localStorage.getItem('theme') || 'system';
let resolved;
if (theme === 'system') {
resolved = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
} else {
resolved = theme;
}
document.documentElement.classList.remove('light', 'dark');
document.documentElement.classList.add(resolved);
} catch (e) {
// Silently fail - theme will be set by ThemeProvider
}
})();
`,
}}
/>
</head>
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
<NextIntlClientProvider messages={messages}>
<AuthProvider>
<AuthInitializer />
<Providers>{children}</Providers>
</AuthProvider>
</NextIntlClientProvider>
</body>
</html>
);
}

View File

@@ -0,0 +1,99 @@
/**
* Homepage / Landing Page
* Main landing page for the FastNext Template project
* Showcases features, tech stack, and provides demos for developers
*/
'use client';
import { useState } from 'react';
import { Link } from '@/lib/i18n/routing';
import { Header } from '@/components/home/Header';
import { HeroSection } from '@/components/home/HeroSection';
import { ContextSection } from '@/components/home/ContextSection';
import { AnimatedTerminal } from '@/components/home/AnimatedTerminal';
import { FeatureGrid } from '@/components/home/FeatureGrid';
import { DemoSection } from '@/components/home/DemoSection';
import { StatsSection } from '@/components/home/StatsSection';
import { TechStackSection } from '@/components/home/TechStackSection';
import { PhilosophySection } from '@/components/home/PhilosophySection';
import { QuickStartCode } from '@/components/home/QuickStartCode';
import { CTASection } from '@/components/home/CTASection';
import { DemoCredentialsModal } from '@/components/home/DemoCredentialsModal';
export default function Home() {
const [demoModalOpen, setDemoModalOpen] = useState(false);
return (
<div className="min-h-screen">
{/* Header Navigation */}
<Header onOpenDemoModal={() => setDemoModalOpen(true)} />
{/* Main Content */}
<main>
{/* Hero Section with CTAs */}
<HeroSection onOpenDemoModal={() => setDemoModalOpen(true)} />
{/* What is this template? */}
<ContextSection />
{/* Animated Terminal with Quick Start */}
<AnimatedTerminal />
{/* 6 Feature Cards Grid */}
<FeatureGrid />
{/* Interactive Demo Cards */}
<DemoSection />
{/* Statistics with Animated Counters */}
<StatsSection />
{/* Tech Stack Grid */}
<TechStackSection />
{/* For Developers, By Developers */}
<PhilosophySection />
{/* Quick Start Code Block */}
<QuickStartCode />
{/* Final CTA Section */}
<CTASection onOpenDemoModal={() => setDemoModalOpen(true)} />
</main>
{/* Footer */}
<footer className="border-t bg-muted/30">
<div className="container mx-auto px-6 py-8">
<div className="flex flex-col md:flex-row items-center justify-between gap-4">
<div className="text-sm text-muted-foreground">
© {new Date().getFullYear()} FastNext Template. MIT Licensed.
</div>
<div className="flex items-center gap-6 text-sm text-muted-foreground">
<Link href="/demos" className="hover:text-foreground transition-colors">
Demo Tour
</Link>
<Link href="/dev" className="hover:text-foreground transition-colors">
Design System
</Link>
<a
href="https://github.com"
target="_blank"
rel="noopener noreferrer"
className="hover:text-foreground transition-colors"
>
GitHub
</a>
<Link href="/dev/docs" className="hover:text-foreground transition-colors">
Documentation
</Link>
</div>
</div>
</div>
</footer>
{/* Shared Demo Credentials Modal */}
<DemoCredentialsModal open={demoModalOpen} onClose={() => setDemoModalOpen(false)} />
</div>
);
}

View File

@@ -1,68 +1,15 @@
import type { Metadata } from 'next';
import { Geist, Geist_Mono } from 'next/font/google';
import './globals.css';
import { Providers } from './providers';
import { AuthProvider } from '@/lib/auth/AuthContext';
import { AuthInitializer } from '@/components/auth';
const geistSans = Geist({
variable: '--font-geist-sans',
subsets: ['latin'],
display: 'swap', // Prevent font from blocking render
preload: true,
});
const geistMono = Geist_Mono({
variable: '--font-geist-mono',
subsets: ['latin'],
display: 'swap', // Prevent font from blocking render
preload: false, // Only preload primary font
});
export const metadata: Metadata = {
title: 'FastNext Template',
description: 'FastAPI + Next.js Template',
};
/**
* Root Layout
*
* Minimal root layout that passes through to locale-specific layouts.
* The actual HTML structure and providers are in [locale]/layout.tsx
* to properly handle locale-specific rendering.
*/
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en" suppressHydrationWarning>
<head>
{/* Theme initialization script - runs before React hydrates to prevent FOUC */}
<script
dangerouslySetInnerHTML={{
__html: `
(function() {
try {
const theme = localStorage.getItem('theme') || 'system';
let resolved;
if (theme === 'system') {
resolved = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
} else {
resolved = theme;
}
document.documentElement.classList.remove('light', 'dark');
document.documentElement.classList.add(resolved);
} catch (e) {
// Silently fail - theme will be set by ThemeProvider
}
})();
`,
}}
/>
</head>
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
<AuthProvider>
<AuthInitializer />
<Providers>{children}</Providers>
</AuthProvider>
</body>
</html>
);
return children;
}

99
frontend/src/app/page.tsx Executable file → Normal file
View File

@@ -1,99 +1,10 @@
/**
* Homepage / Landing Page
* Main landing page for the FastNext Template project
* Showcases features, tech stack, and provides demos for developers
* Root page - redirects to default locale
*/
'use client';
import { redirect } from 'next/navigation';
import { useState } from 'react';
import Link from 'next/link';
import { Header } from '@/components/home/Header';
import { HeroSection } from '@/components/home/HeroSection';
import { ContextSection } from '@/components/home/ContextSection';
import { AnimatedTerminal } from '@/components/home/AnimatedTerminal';
import { FeatureGrid } from '@/components/home/FeatureGrid';
import { DemoSection } from '@/components/home/DemoSection';
import { StatsSection } from '@/components/home/StatsSection';
import { TechStackSection } from '@/components/home/TechStackSection';
import { PhilosophySection } from '@/components/home/PhilosophySection';
import { QuickStartCode } from '@/components/home/QuickStartCode';
import { CTASection } from '@/components/home/CTASection';
import { DemoCredentialsModal } from '@/components/home/DemoCredentialsModal';
export default function Home() {
const [demoModalOpen, setDemoModalOpen] = useState(false);
return (
<div className="min-h-screen">
{/* Header Navigation */}
<Header onOpenDemoModal={() => setDemoModalOpen(true)} />
{/* Main Content */}
<main>
{/* Hero Section with CTAs */}
<HeroSection onOpenDemoModal={() => setDemoModalOpen(true)} />
{/* What is this template? */}
<ContextSection />
{/* Animated Terminal with Quick Start */}
<AnimatedTerminal />
{/* 6 Feature Cards Grid */}
<FeatureGrid />
{/* Interactive Demo Cards */}
<DemoSection />
{/* Statistics with Animated Counters */}
<StatsSection />
{/* Tech Stack Grid */}
<TechStackSection />
{/* For Developers, By Developers */}
<PhilosophySection />
{/* Quick Start Code Block */}
<QuickStartCode />
{/* Final CTA Section */}
<CTASection onOpenDemoModal={() => setDemoModalOpen(true)} />
</main>
{/* Footer */}
<footer className="border-t bg-muted/30">
<div className="container mx-auto px-6 py-8">
<div className="flex flex-col md:flex-row items-center justify-between gap-4">
<div className="text-sm text-muted-foreground">
© {new Date().getFullYear()} FastNext Template. MIT Licensed.
</div>
<div className="flex items-center gap-6 text-sm text-muted-foreground">
<Link href="/demos" className="hover:text-foreground transition-colors">
Demo Tour
</Link>
<Link href="/dev" className="hover:text-foreground transition-colors">
Design System
</Link>
<a
href="https://github.com"
target="_blank"
rel="noopener noreferrer"
className="hover:text-foreground transition-colors"
>
GitHub
</a>
<Link href="/dev/docs" className="hover:text-foreground transition-colors">
Documentation
</Link>
</div>
</div>
</div>
</footer>
{/* Shared Demo Credentials Modal */}
<DemoCredentialsModal open={demoModalOpen} onClose={() => setDemoModalOpen(false)} />
</div>
);
export default function RootPage() {
// Redirect to default locale (en)
redirect('/en');
}

View File

@@ -5,8 +5,8 @@
'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Link } from '@/lib/i18n/routing';
import { usePathname } from '@/lib/i18n/routing';
import { cn } from '@/lib/utils';
import {
LayoutDashboard,

View File

@@ -5,8 +5,8 @@
'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Link } from '@/lib/i18n/routing';
import { usePathname } from '@/lib/i18n/routing';
import { ChevronRight } from 'lucide-react';
interface BreadcrumbItem {

View File

@@ -6,7 +6,8 @@
'use client';
import { useState, useCallback } from 'react';
import { useSearchParams, useRouter } from 'next/navigation';
import { useSearchParams } from 'next/navigation';
import { useRouter } from '@/lib/i18n/routing';
import { Plus } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {

View File

@@ -6,7 +6,8 @@
'use client';
import { useState, useCallback } from 'react';
import { useSearchParams, useRouter } from 'next/navigation';
import { useSearchParams } from 'next/navigation';
import { useRouter } from '@/lib/i18n/routing';
import { UserPlus } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {

View File

@@ -6,7 +6,8 @@
'use client';
import { useState, useCallback } from 'react';
import { useSearchParams, useRouter } from 'next/navigation';
import { useSearchParams } from 'next/navigation';
import { useRouter } from '@/lib/i18n/routing';
import { Plus } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useAuth } from '@/lib/auth/AuthContext';

View File

@@ -7,7 +7,7 @@
'use client';
import { useEffect, useState } from 'react';
import { useRouter, usePathname } from 'next/navigation';
import { useRouter, usePathname } from '@/lib/i18n/routing';
import { useAuth } from '@/lib/auth/AuthContext';
import { useMe } from '@/lib/api/hooks/useAuth';
import { AuthLoadingSkeleton } from '@/components/layout';

View File

@@ -7,7 +7,7 @@
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

View File

@@ -7,7 +7,7 @@
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

View File

@@ -7,7 +7,7 @@
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

View File

@@ -7,7 +7,7 @@
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

View File

@@ -8,7 +8,7 @@
'use client';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { ChevronRight, Home } from 'lucide-react';
import { cn } from '@/lib/utils';

View File

@@ -8,8 +8,8 @@
'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Link } from '@/lib/i18n/routing';
import { usePathname } from '@/lib/i18n/routing';
import {
Code2,
Palette,

View File

@@ -9,7 +9,7 @@ import { useEffect, useState, useRef } from 'react';
import { motion } from 'framer-motion';
import { Terminal, Play } from 'lucide-react';
import { Button } from '@/components/ui/button';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
const commands = [
{ text: '# Clone the repository', delay: 0 },

View File

@@ -5,7 +5,7 @@
'use client';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { motion } from 'framer-motion';
import { Github, Star, Play, ArrowRight } from 'lucide-react';
import { Button } from '@/components/ui/button';

View File

@@ -6,7 +6,7 @@
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { Copy, Check } from 'lucide-react';
import {
Dialog,

View File

@@ -5,7 +5,7 @@
'use client';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { motion } from 'framer-motion';
import { Play, Layers, ShieldCheck, UserCircle } from 'lucide-react';
import { Button } from '@/components/ui/button';

View File

@@ -5,7 +5,7 @@
'use client';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { motion } from 'framer-motion';
import { ArrowRight, LucideIcon } from 'lucide-react';

View File

@@ -6,7 +6,7 @@
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { Menu, X, Github, Star } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet';

View File

@@ -5,7 +5,7 @@
'use client';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
import { motion } from 'framer-motion';
import { ArrowRight, Github, Play } from 'lucide-react';
import { Button } from '@/components/ui/button';

View File

@@ -5,7 +5,7 @@
'use client';
import Link from 'next/link';
import { Link } from '@/lib/i18n/routing';
export function Footer() {
const currentYear = new Date().getFullYear();

View File

@@ -6,8 +6,8 @@
'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Link } from '@/lib/i18n/routing';
import { usePathname } from '@/lib/i18n/routing';
import { useAuth } from '@/lib/auth/AuthContext';
import { useLogout } from '@/lib/api/hooks/useAuth';
import {

View File

@@ -9,8 +9,9 @@ const intlMiddleware = createMiddleware(routing);
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// Block access to /dev routes in production (before locale handling)
if (pathname.startsWith('/dev')) {
// Block access to /dev routes in production (handles both /dev and /[locale]/dev)
// Match: /dev, /en/dev, /it/dev, etc.
if (pathname === '/dev' || pathname.match(/^\/[a-z]{2}\/dev($|\/)/)) {
const isProduction = process.env.NODE_ENV === 'production';
if (isProduction) {