|
| 1 | +# Client Project Structure |
| 2 | + |
| 3 | +This document describes the organization of the client-side application, explaining the purpose of each folder and providing guidelines for maintaining a clean, scalable codebase. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The client is a React + TypeScript application built with Vite. It follows a feature-based architecture where related functionality is grouped together. |
| 8 | + |
| 9 | +## Root Structure |
| 10 | + |
| 11 | +``` |
| 12 | +client/ |
| 13 | +├── src/ |
| 14 | +│ ├── main.tsx # Application entry point |
| 15 | +│ ├── App.tsx # Root component with routing |
| 16 | +│ ├── vite-env.d.ts # Vite type definitions |
| 17 | +│ ├── assets/ # Static assets (images, fonts, etc.) |
| 18 | +│ ├── auth/ # Authentication logic and hooks |
| 19 | +│ ├── components/ # Shared UI components |
| 20 | +│ ├── data/ # Global data management (React Query) |
| 21 | +│ ├── features/ # Feature-based modules |
| 22 | +│ ├── layout/ # Layout components (navbar, etc.) |
| 23 | +│ ├── routes/ # Route definitions and protected routes |
| 24 | +│ └── styles/ # Global styles |
| 25 | +├── index.html # HTML entry point |
| 26 | +├── package.json # Dependencies and scripts |
| 27 | +├── vite.config.ts # Vite configuration |
| 28 | +└── tsconfig.json # TypeScript configuration |
| 29 | +``` |
| 30 | + |
| 31 | +## Folder Purposes |
| 32 | + |
| 33 | +### `/src/assets` |
| 34 | + |
| 35 | +Static assets like images, logos, fonts, and other media files. |
| 36 | + |
| 37 | +- Keep assets organized by type or feature |
| 38 | +- Use meaningful file names |
| 39 | +- Optimize images before adding |
| 40 | + |
| 41 | +### `/src/auth` |
| 42 | + |
| 43 | +Authentication-related logic: |
| 44 | + |
| 45 | +- Authentication hooks |
| 46 | +- Auth context providers |
| 47 | +- Token management |
| 48 | +- Login/logout utilities |
| 49 | + |
| 50 | +### `/src/components` |
| 51 | + |
| 52 | +**Globally shared UI components** used across multiple features: |
| 53 | + |
| 54 | +- Generic, reusable components (Button, Modal, ErrorBox, Loader, etc.) |
| 55 | +- Should NOT contain feature-specific logic |
| 56 | +- Should be well-documented with props interfaces |
| 57 | + |
| 58 | +**When to add a component here:** |
| 59 | + |
| 60 | +- Component is used in 2+ different features |
| 61 | +- Component is generic and has no feature-specific dependencies |
| 62 | +- Component represents a common UI pattern |
| 63 | + |
| 64 | +### `/src/data` |
| 65 | + |
| 66 | +Global data management: |
| 67 | + |
| 68 | +- React Query configuration and setup |
| 69 | +- Global query hooks (if not feature-specific) |
| 70 | +- API client configuration |
| 71 | +- Data type definitions used across multiple features |
| 72 | + |
| 73 | +### `/src/features` |
| 74 | + |
| 75 | +**Feature-based modules** - each feature is self-contained: |
| 76 | + |
| 77 | +``` |
| 78 | +features/ |
| 79 | +├── dashboard/ # Dashboard feature |
| 80 | +├── login/ # Login feature |
| 81 | +├── search/ # Search feature |
| 82 | +└── trainee-profile/ # Trainee profile feature (see detailed structure below) |
| 83 | +``` |
| 84 | + |
| 85 | +### `/src/layout` |
| 86 | + |
| 87 | +Layout components that define the application structure: |
| 88 | + |
| 89 | +- Navigation bars |
| 90 | +- Sidebars |
| 91 | +- Page wrappers |
| 92 | +- Footer components |
| 93 | + |
| 94 | +### `/src/routes` |
| 95 | + |
| 96 | +Routing configuration: |
| 97 | + |
| 98 | +- Route definitions |
| 99 | +- Protected route wrappers |
| 100 | +- Route guards |
| 101 | +- Navigation utilities |
| 102 | + |
| 103 | +### `/src/styles` |
| 104 | + |
| 105 | +Global styles: |
| 106 | + |
| 107 | +- CSS reset/normalize |
| 108 | +- Theme variables |
| 109 | +- Global utility classes |
| 110 | +- Typography styles |
| 111 | + |
| 112 | +## Feature Structure |
| 113 | + |
| 114 | +Each feature should follow this pattern: |
| 115 | + |
| 116 | +``` |
| 117 | +feature-name/ |
| 118 | +├── [Feature].ts # Feature-specific type definitions (named after main type) |
| 119 | +├── [Feature]Page.tsx # Main page component |
| 120 | +├── components/ # Shared components within this feature |
| 121 | +├── hooks/ # Feature-specific custom hooks |
| 122 | +├── context/ # Feature-specific context (if needed) |
| 123 | +├── utils/ # Feature-specific utilities |
| 124 | +└── [sub-features]/ # Sub-feature folders |
| 125 | +``` |
| 126 | + |
| 127 | +### Example: Trainee Profile Feature |
| 128 | + |
| 129 | +``` |
| 130 | +trainee-profile/ |
| 131 | +├── TraineePage.tsx # Main entry point |
| 132 | +├── components/ # Shared UI components for trainee profile |
| 133 | +│ └── MarkdownText.tsx |
| 134 | +├── context/ # State management for trainee profile |
| 135 | +│ ├── TraineeProfileContext.tsx |
| 136 | +│ └── TraineeProfileProvider.tsx |
| 137 | +├── utils/ # Helper functions |
| 138 | +│ └── formHelper.ts |
| 139 | +├── profile/ # Main profile layout |
| 140 | +│ ├── ProfileSidebar.tsx |
| 141 | +│ └── components/ |
| 142 | +│ ├── TraineeProfile.tsx |
| 143 | +│ ├── ProfileNav.tsx |
| 144 | +│ └── EditSaveButton.tsx |
| 145 | +├── personal-info/ # Personal information tab |
| 146 | +│ ├── PersonalInfo.tsx |
| 147 | +│ └── data/ |
| 148 | +│ ├── useTraineeInfoData.tsx |
| 149 | +│ └── useSaveTraineeInfo.tsx |
| 150 | +├── contact/ # Contact information tab |
| 151 | +│ └── ContactInfo.tsx |
| 152 | +├── education/ # Education information tab |
| 153 | +│ └── EducationInfo.tsx |
| 154 | +├── employment/ # Employment information tab |
| 155 | +│ └── EmploymentInfo.tsx |
| 156 | +└── interactions/ # Interactions tab |
| 157 | + └── InteractionsInfo.tsx |
| 158 | +``` |
| 159 | + |
| 160 | +### Example: Cohorts Feature |
| 161 | + |
| 162 | +``` |
| 163 | +cohorts/ |
| 164 | +├── Cohorts.ts # Type definitions for cohort data |
| 165 | +├── CohortsPage.tsx # Main page component |
| 166 | +├── components/ # Cohort-specific components |
| 167 | +│ ├── CohortAccordion.tsx |
| 168 | +│ └── TraineeAvatar.tsx |
| 169 | +└── data/ # Data fetching hooks |
| 170 | + └── useCohortsData.tsx |
| 171 | +``` |
| 172 | + |
| 173 | +**Note:** The trainee-profile feature no longer has a root-level type file. Trainee types have been moved to `/src/data/types/Trainee.ts` as they are used across multiple features. |
| 174 | + |
| 175 | +## Maintenance Guidelines |
| 176 | + |
| 177 | +### Where to Put New Code |
| 178 | + |
| 179 | +**Components:** |
| 180 | + |
| 181 | +- Used across multiple features → `/src/components` |
| 182 | +- Used within one feature → `/src/features/[feature-name]/components` |
| 183 | + |
| 184 | +**Hooks:** |
| 185 | + |
| 186 | +- Shared across features → `/src/hooks` |
| 187 | +- Feature-specific → `/src/features/[feature-name]/hooks` |
| 188 | +- Always use `use` prefix |
| 189 | + |
| 190 | +**Types:** |
| 191 | + |
| 192 | +- Shared across features → `/src/data` or relevant top-level folder |
| 193 | +- Feature-specific → `/src/features/[feature-name]/[TypeName].ts` |
| 194 | + |
| 195 | +**Utilities:** |
| 196 | + |
| 197 | +- Shared across features → Create `/src/utils` if needed |
| 198 | +- Feature-specific → `/src/features/[feature-name]/utils` |
| 199 | + |
| 200 | +## Code Organization Principles |
| 201 | + |
| 202 | +### 1. Feature-First Organization |
| 203 | + |
| 204 | +Group code by feature rather than by type. This makes it easier to: |
| 205 | + |
| 206 | +- Find related code |
| 207 | +- Understand feature boundaries |
| 208 | +- Remove or refactor features independently |
| 209 | + |
| 210 | +### 2. Colocation |
| 211 | + |
| 212 | +Keep related code close together: |
| 213 | + |
| 214 | +- Components with their hooks and utils |
| 215 | +- Types near where they're used |
| 216 | +- Tests alongside implementation |
| 217 | + |
| 218 | +### 3. Single Responsibility |
| 219 | + |
| 220 | +Each file should have one clear purpose: |
| 221 | + |
| 222 | +- One component per file |
| 223 | +- One hook per file (unless very closely related) |
| 224 | +- Focused utility functions |
| 225 | + |
| 226 | +### 4. Clear Boundaries |
| 227 | + |
| 228 | +Maintain clear separation between: |
| 229 | + |
| 230 | +- **Global** (shared across features) vs **Feature-specific** |
| 231 | +- **UI Components** vs **Business Logic** |
| 232 | +- **Presentation** vs **Container** components |
| 233 | + |
| 234 | +### 5. Consistent Naming |
| 235 | + |
| 236 | +Follow these conventions: |
| 237 | + |
| 238 | +- **Components**: PascalCase (e.g., `TraineeProfile.tsx`) |
| 239 | +- **Hooks**: camelCase with `use` prefix (e.g., `useTraineeData.tsx`) |
| 240 | +- **Utilities**: camelCase (e.g., `formHelper.ts`) |
| 241 | +- **Type files**: PascalCase, named after the main type (e.g., `Trainee.ts`, `User.ts`) |
| 242 | +- **Constants**: UPPER_SNAKE_CASE |
0 commit comments