This document outlines the conventions and standards to follow when contributing to the Univ-Check UI project. Please adhere to these guidelines to ensure code consistency and maintainability.
- Project Structure
- Naming Conventions
- Component Organization
- Architecture and Patterns
- Styling and UI Components
- State Management
- Forms
- Internationalization
- Testing
- Commit Format
src/
├── app/ # Next.js App Router routes and pages
│ ├── auth/ # Authentication routes (formerly (auth))
│ ├── board/ # Main application routes (formerly dashboard)
│ └── ...
├── components/ # Reusable UI components
│ ├── ui/ # Base components (shadcn/ui only)
│ ├── enhanced/ # Enhanced shadcn components with logic
│ ├── shared/ # Custom shared components
│ │ ├── navigation/ # Navigation-related components
│ │ ├── theme/ # Theme-related components
│ │ └── others/ # Other shared components
│ └── ...
├── config/ # Global configuration
│ ├── constants.ts # Application constants
│ ├── messages.ts # Error and success messages
│ ├── routes.ts # Centralized route definitions
│ └── navigation-items.tsx # Navigation configuration
├── hooks/ # Custom React hooks
│ ├── queries/ # TanStack Query hooks
│ └── ...
├── lib/ # Utilities and functions
│ └── utils.ts # Utility functions
├── schema/ # Validation schemas (Zod)
├── server/ # Server-side logic
│ ├── services/ # Business services
│ └── ...
└── utils/ # Specific utilities
├── providers/ # React providers
└── ...
-
Use
kebab-case
for folder names- Example:
sign-in/
,board/
- Example:
-
For component files, use dot notation with descriptive suffixes instead of hyphens
- Example:
app.sidebar.tsx
,feedback.dialog.tsx
,team.switcher.tsx
- Example:
-
For pages, use
page.tsx
(Next.js convention) -
For form components, use the convention:
{name}.form.tsx
- Example:
sign-in.form.tsx
- Example:
-
For layouts, use
layout.tsx
(Next.js convention) -
For custom components, use the convention:
{name}.{component-type}.tsx
- Example:
contacts.table.tsx
,user.dropdown.tsx
- Example:
-
For custom hooks, prefix with
use-
- Example:
use-mobile.ts
- Example:
-
For query hooks, organize by feature and use
.query.ts
suffix- Example:
use-auth.query.ts
- Example:
- Use
PascalCase
for React component names- Example:
SignInForm
,ModeToggle
- Example:
- Use
PascalCase
for class names- Example:
AuthService
,AuthenticationError
- Example:
- Use
camelCase
for function, method, and variable names- Example:
onSubmit
,formError
- Example:
-
src/components/ui/: Reserved EXCLUSIVELY for native shadcn/ui components. Only minimal style overrides are allowed here, NO additional logic.
-
src/components/enhanced/: For components that extend shadcn/ui components with additional logic or significant customizations.
- Example: An enhanced
Button
with loading states or analytics tracking
- Example: An enhanced
-
src/components/shared/: For custom, reusable components across application areas
- navigation/: Navigation-related components (app.sidebar, search.form, team.switcher, user.dropdown)
- theme/: Theme-related components (mode-toggle)
- others/: Other shared components (feedback.dialog)
-
src/app/(feature)/components/: For components specific to a feature or page
- Can include subdirectories to categorize by type (e.g.,
table/
,form/
)
- Can include subdirectories to categorize by type (e.g.,
- Base shadcn/ui components: Simple name (
button.tsx
) - Enhanced components:
{name}.enhanced.tsx
(e.g.,button.enhanced.tsx
) - Custom components:
{name}.{component-type}.tsx
(e.g.,contacts.table.tsx
) - Specialized components:
{name}.{specific-type}.tsx
(e.g.,professor-list.table.tsx
)
- Page components: Should only contain page structure, no business logic
- Form components: Should be placed in a
components
folder adjacent to the associated page - UI components: Should be in the appropriate components directory based on their type
- Navigation: Navigation items should be defined in
src/config/navigation-items.tsx
- Use a class-oriented approach for services
- Place services in
src/server/services/
- Name service files:
{service-name}.service.ts
- Services should be responsible for business logic and API calls
Example:
// src/server/services/auth.service.ts
export class AuthService {
static async signIn(credentials) {
/* ... */
}
static async signOut() {
/* ... */
}
}
- Place TanStack Query hooks in
src/hooks/queries/{feature}.query.ts
- Export query keys in the same file
- Prefix mutation hooks with
use
and suffix withMutation
Example:
// src/hooks/queries/auth.query.ts
export const authQueryKeys = {
/* ... */
};
export function useSignInMutation() {
/* ... */
}
export function useCurrentUser() {
/* ... */
}
- Place Next.js middleware in
src/middleware.ts
- Use middleware for route protection, redirects, and request/response modifications
- Use Tailwind CSS for styling
- Use shadcn/ui components as the foundation for the user interface
- Prefer Tailwind classes integrated into components rather than separate CSS files
- For complex variations, use
cva
(class-variance-authority) - When extending shadcn components with styling only, you can create a variant in the same file
- When adding logic, create an enhanced version in
src/components/enhanced/
- Use React icons and Remixicon for icons - import from
@remixicon/react
- Use TanStack Query for server-related state management
- Use TanStack Table for table-related state
- Use React hooks (
useState
,useReducer
) for local state - Avoid global state managers (Redux, Zustand) unless absolutely necessary
- Use React contexts for state shared across multiple components
- Use
react-hook-form
for all forms - Use
zod
for schema validation - Place validation schemas in
src/schema/{form-name}.schema.ts
- Use shadcn/ui
Form
components
Example:
const form = useForm<InputType>({
resolver: zodResolver(validationSchema),
defaultValues: {
/* ... */
},
});
- Centralize all messages in
src/config/messages.ts
- Structure messages by feature
- Use descriptive keys
- Place tests next to the tested file with the extension
.test.ts(x)
- Use Vitest for unit tests
- Use Playwright for e2e tests
- Ensure each component and service has appropriate tests
Follow the conventional commit convention:
<type>(<scope>): <description>
[optional body]
[optional footer]
Common types:
feat
: New featurefix
: Bug fixdocs
: Documentation changesstyle
: Style changes (no code change)refactor
: Code refactoringtest
: Adding or modifying testschore
: Maintenance tasks
Example:
feat(auth): add sign-in page
- Add sign-in form
- Integrate with authentication service
- Add unit tests
This guide is evolving and will be updated as the project progresses. Contributors are encouraged to propose improvements to these conventions.