This document maps out the component hierarchy and relationships in SaaSPilot.
Located in /app and /components
- Location:
/app/layout.tsx - Type: Server Component
- Purpose: Root layout with providers
- Children: All pages
- Providers:
- SessionProvider (NextAuth)
- ThemeProvider (next-themes)
- CreditsProvider (Credit context)
- IntlProvider (next-intl)
Located in /components/auth
- Location:
/components/auth/login-form.tsx - Type: Client Component
- Dependencies:
loginserver action- React Hook Form
- Zod validation
- Features: Email/password login, OAuth buttons
- Used in:
/app/auth/login/page.tsx
- Location:
/components/auth/register-form.tsx - Type: Client Component
- Dependencies:
registerserver action- React Hook Form
- Zod validation
- Features: User registration, email verification
- Used in:
/app/auth/register/page.tsx
- Location:
/components/auth/new-password-form.tsx - Type: Client Component
- Purpose: Password reset form
- Dependencies:
newPasswordserver action
- Location:
/components/auth/reset-form.tsx - Type: Client Component
- Purpose: Request password reset
- Dependencies:
resetserver action
- Location:
/components/auth/error-card.tsx - Type: Client Component
- Purpose: Display auth errors
- Used in:
/app/auth/error/page.tsx
- Location:
/components/auth/social.tsx - Type: Client Component
- Purpose: OAuth login buttons (Google, GitHub)
- Dependencies: NextAuth signIn
Located in /components/ui
Base UI components built on Radix UI:
button.tsx- Button componentcard.tsx- Card containerdialog.tsx- Modal dialogdropdown-menu.tsx- Dropdown menuform.tsx- Form componentsinput.tsx- Text inputlabel.tsx- Form labelselect.tsx- Select dropdownseparator.tsx- Dividersheet.tsx- Side panelswitch.tsx- Toggle switchtable.tsx- Data tabletabs.tsx- Tab navigationtoast.tsx- Notification toast- And more...
Usage: Import from @/components/ui/[component]
- Location:
/components/Navbar.tsx - Type: Client Component
- Purpose: Main navigation bar
- Features:
- Logo and branding
- Language switcher
- User menu
- Mobile responsive
- Used in: Marketing pages
- Location:
/components/Dashboard.tsx(or similar) - Type: Client Component
- Purpose: Dashboard navigation
- Used in: Protected dashboard pages
Located in /components and /app/(marketing)
- Location:
/components/Hero.tsx(or in page) - Type: Server/Client Component
- Purpose: Landing page hero section
- Features: CTA, animations
- Type: Server Component
- Purpose: Feature showcase
- Used in: Landing page
- Location:
/components/Testimonials/ - Purpose: Customer testimonials
- Used in: Landing, About pages
- Purpose: Pricing cards/table
- Features:
- Display credit packages
- Stripe checkout integration
- Used in: Pricing page
Located in /app/(protected)/dashboard
- Type: Client Component
- Purpose: Display user's credit balance
- Dependencies: useCredits hook
- Used in: Dashboard pages
- Type: Server Component
- Purpose: Display purchase history
- Data Source: Purchase model via Prisma
- Used in: Billing page
- Type: Client Component
- Purpose: User settings management
- Dependencies:
updateSettingsserver action - Used in: Settings page
Located in /components/Common
- Type: Client Component
- Purpose: Language selection dropdown
- Languages: English, German, Arabic
- Used in: Navbar, Footer
- Type: Client Component
- Purpose: Dark/light mode toggle
- Dependencies: next-themes
- Used in: Navbar
- Type: Server Component
- Purpose: Site footer
- Used in: All marketing pages
App Root
├── RootLayout (Providers)
│ ├── (marketing)
│ │ ├── Home Page
│ │ │ ├── Navbar
│ │ │ ├── Hero
│ │ │ ├── Features
│ │ │ ├── Testimonials
│ │ │ ├── Pricing
│ │ │ └── Footer
│ │ ├── About Page
│ │ ├── Contact Page
│ │ └── Pricing Page
│ │
│ ├── (auth)
│ │ ├── Login Page
│ │ │ └── LoginForm
│ │ │ ├── Social (OAuth)
│ │ │ └── UI Components
│ │ ├── Register Page
│ │ │ └── RegisterForm
│ │ ├── Reset Page
│ │ │ └── ResetForm
│ │ ├── New Password Page
│ │ │ └── NewPasswordForm
│ │ └── Error Page
│ │ └── ErrorCard
│ │
│ └── (protected)
│ └── Dashboard
│ ├── DashboardNav
│ ├── Dashboard Page
│ │ ├── CreditBalance
│ │ └── Dashboard Stats
│ ├── Billing Page
│ │ ├── CreditBalance
│ │ ├── Pricing Cards
│ │ └── PurchaseHistory
│ └── Settings Page
│ └── SettingsForm
LoginForm → login action → NextAuth → Session → Redirect
Pricing Card → createStripeSession action → Stripe Checkout
→ Payment Success → Webhook → Update Credits → Dashboard
SettingsForm → updateSettings action → Prisma → Database
→ Revalidate → Updated UI
<ChildComponent prop1="value" prop2={data} />const result = await serverAction(data)const { credits } = useCredits()const user = useCurrentUser()
const session = useSession()- Location:
/hooks/use-current-user.ts - Purpose: Get current user on client
- Returns: User object or undefined
- Usage: Client components needing user data
- Location:
/hooks/use-current-role.ts - Purpose: Get current user role
- Returns: UserRole or undefined
- Usage: Role-based UI rendering
- Location:
/context/CreditsContext.tsx - Purpose: Access and manage credits
- Returns:
{ credits, addCredits, spendCredits } - Usage: Components showing/using credits
- Landing pages
- Dashboard pages (data fetching)
- Static content
- SEO-important pages
- Forms with state
- Interactive UI
- Event handlers
- Browser APIs
- Hooks usage
-
Decide Server vs Client
- Default to Server Component
- Use Client only if needed
-
Naming Convention
- PascalCase for components
- Descriptive names (e.g.,
UserProfileCard)
-
File Organization
- Group related components
- Co-locate with features when specific
-
Props Interface
interface ComponentProps { required: string optional?: number children?: React.ReactNode }
-
Documentation
/** * @ai-context Component purpose * @ai-dependencies List dependencies */
'use client'
export function MyForm() {
const [state, formAction] = useFormState(serverAction, null)
return (
<form action={formAction}>
{/* form fields */}
</form>
)
}// Server Component
export default async function DataPage() {
const data = await db.model.findMany()
return <DataList data={data} />
}
// Client Component
'use client'
export function DataList({ data }: { data: Item[] }) {
// Interactive rendering
}import { auth } from '@/auth'
export default async function ProtectedPage() {
const session = await auth()
if (!session) {
redirect('/auth/login')
}
return <ProtectedContent />
}<div className="flex items-center gap-4 rounded-lg border p-6">
{/* content */}
</div><div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
{/* responsive grid */}
</div><div className="bg-white dark:bg-gray-900 text-black dark:text-white">
{/* theme-aware */}
</div>- Determine if Server or Client component
- Create in appropriate directory
- Define Props interface
- Add TypeScript types
- Implement component logic
- Add proper documentation
- Test rendering and functionality
- Update this component map if significant
// /components/features/MyComponent.tsx
'use client' // if needed
import { ComponentProps } from './types'
/**
* @ai-context Brief description
* @ai-dependencies List deps
* @ai-modify-safe Yes/No
*/
export function MyComponent({ prop1, prop2 }: ComponentProps) {
// Implementation
return (
<div>
{/* JSX */}
</div>
)
}- Architecture - System architecture
- Coding Patterns - Code patterns
- Database Schema - Data models