# Component Patterns - tOS Frontend ## Layout Component Pattern ```tsx // src/components/layout/sidebar.tsx 'use client'; import { usePathname } from 'next/navigation'; import { motion } from 'framer-motion'; import { useSidebarStore } from '@/stores/sidebar-store'; export function Sidebar({ locale }: { locale: string }) { const { isExpanded, toggleSidebar } = useSidebarStore(); const pathname = usePathname(); return ( {/* Content */} ); } ``` ## Page with Metadata Pattern ```tsx // page.tsx (Server Component) import { Metadata } from 'next'; import { getTranslations } from 'next-intl/server'; import { ContentComponent } from './content-component'; export async function generateMetadata(): Promise { const t = await getTranslations('namespace'); return { title: t('title') }; } export default function Page() { return ; } // content-component.tsx (Client Component) 'use client'; import { useTranslations } from 'next-intl'; export function ContentComponent() { const t = useTranslations('namespace'); return
{t('key')}
; } ``` ## Zustand Store Pattern ```tsx // src/stores/sidebar-store.ts import { create } from 'zustand'; import { persist } from 'zustand/middleware'; interface SidebarState { isExpanded: boolean; toggleSidebar: () => void; } export const useSidebarStore = create()( persist( (set) => ({ isExpanded: true, toggleSidebar: () => set((state) => ({ isExpanded: !state.isExpanded })), }), { name: 'tos-sidebar-state', partialize: (state) => ({ isExpanded: state.isExpanded }), } ) ); ``` ## Animation Pattern with Framer Motion ```tsx import { motion } from 'framer-motion'; // Staggered list animation {items.map((item, index) => ( {item.content} ))} ``` ## shadcn/ui Component with Variants ```tsx // src/components/ui/button.tsx import { cva, type VariantProps } from 'class-variance-authority'; const buttonVariants = cva( 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors', { variants: { variant: { default: 'bg-primary text-primary-foreground hover:bg-primary/90', destructive: 'bg-destructive text-destructive-foreground', outline: 'border border-input bg-background hover:bg-accent', ghost: 'hover:bg-accent hover:text-accent-foreground', }, size: { default: 'h-9 px-4 py-2', sm: 'h-8 px-3 text-xs', lg: 'h-10 px-8', icon: 'h-9 w-9', }, }, defaultVariants: { variant: 'default', size: 'default', }, } ); export interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { asChild?: boolean; } ``` ## Provider Composition Pattern ```tsx // src/components/providers/index.tsx 'use client'; export function Providers({ children }: { children: ReactNode }) { return ( {children} ); } ``` ## i18n Usage Pattern ```tsx // In components import { useTranslations } from 'next-intl'; export function Component() { const t = useTranslations('namespace'); return {t('key', { param: 'value' })}; } // In server components import { getTranslations } from 'next-intl/server'; export async function ServerComponent() { const t = await getTranslations('namespace'); return {t('key')}; } ``` ## Protected Route Layout Pattern ```tsx // src/app/[locale]/(auth)/layout.tsx 'use client'; export default function AuthLayout({ children, params: { locale } }) { const { isExpanded } = useSidebarStore(); return (
{children}
); } ```