diff --git a/frontend/src/app/(auth)/layout.tsx b/frontend/src/app/(auth)/layout.tsx index 68ccdc0..abdaf8a 100644 --- a/frontend/src/app/(auth)/layout.tsx +++ b/frontend/src/app/(auth)/layout.tsx @@ -1,4 +1,5 @@ import type { Metadata } from 'next'; +import { AuthLayoutClient } from '@/components/auth/AuthLayoutClient'; export const metadata: Metadata = { title: 'Authentication', @@ -9,11 +10,5 @@ export default function AuthLayout({ }: { children: React.ReactNode; }) { - return ( -
-
- {children} -
-
- ); + return {children}; } diff --git a/frontend/src/components/auth/AuthLayoutClient.tsx b/frontend/src/components/auth/AuthLayoutClient.tsx new file mode 100644 index 0000000..226f2b3 --- /dev/null +++ b/frontend/src/components/auth/AuthLayoutClient.tsx @@ -0,0 +1,30 @@ +/** + * AuthLayoutClient Component + * Client-side wrapper for auth layout with theme toggle + */ + +'use client'; + +import { ThemeToggle } from '@/components/theme/ThemeToggle'; + +interface AuthLayoutClientProps { + children: React.ReactNode; +} + +export function AuthLayoutClient({ children }: AuthLayoutClientProps) { + return ( +
+ {/* Theme toggle in top-right corner */} +
+ +
+ + {/* Auth card */} +
+
+ {children} +
+
+
+ ); +} diff --git a/frontend/tests/components/auth/AuthLayoutClient.test.tsx b/frontend/tests/components/auth/AuthLayoutClient.test.tsx new file mode 100644 index 0000000..3723a42 --- /dev/null +++ b/frontend/tests/components/auth/AuthLayoutClient.test.tsx @@ -0,0 +1,79 @@ +import { render, screen } from '@testing-library/react'; +import { AuthLayoutClient } from '@/components/auth/AuthLayoutClient'; +import { useTheme } from '@/components/theme/ThemeProvider'; + +// Mock ThemeProvider +jest.mock('@/components/theme/ThemeProvider', () => ({ + useTheme: jest.fn(), +})); + +describe('AuthLayoutClient', () => { + beforeEach(() => { + (useTheme as jest.Mock).mockReturnValue({ + theme: 'light', + setTheme: jest.fn(), + resolvedTheme: 'light', + }); + }); + + it('should render children', () => { + render( + +
Test Content
+
+ ); + + expect(screen.getByText('Test Content')).toBeInTheDocument(); + }); + + it('should render theme toggle', () => { + render( + +
Test Content
+
+ ); + + // Theme toggle is rendered as a button with aria-label + const themeToggle = screen.getByRole('button', { name: /toggle theme/i }); + expect(themeToggle).toBeInTheDocument(); + }); + + it('should have proper layout structure', () => { + const { container } = render( + +
Test Content
+
+ ); + + // Check for main container with proper classes + const mainContainer = container.querySelector('.relative.flex.min-h-screen'); + expect(mainContainer).toBeInTheDocument(); + + // Check for card container + const cardContainer = container.querySelector('.rounded-lg.border.bg-card'); + expect(cardContainer).toBeInTheDocument(); + }); + + it('should position theme toggle in top-right corner', () => { + const { container } = render( + +
Test Content
+
+ ); + + // Check for theme toggle container with absolute positioning + const toggleContainer = container.querySelector('.absolute.right-4.top-4'); + expect(toggleContainer).toBeInTheDocument(); + }); + + it('should render card with proper padding and styling', () => { + const { container } = render( + +
Test Content
+
+ ); + + const card = container.querySelector('.p-8.shadow-sm'); + expect(card).toBeInTheDocument(); + }); +});