From 1306b620f5478b2b3010ce63c8e8eef4390fa556 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 13:49:49 +0000 Subject: [PATCH 1/3] Initial plan From 0ce718a404f5f22f2c4fc29e4451dbbadaeafbec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 13:53:42 +0000 Subject: [PATCH 2/3] Fix package.json overrides conflict and encoding issues in config files Co-authored-by: Vardhan-ysh <116566154+Vardhan-ysh@users.noreply.github.com> --- .eslintrc.mjs | Bin 904 -> 454 bytes package-lock.json | 14 -------------- package.json | 3 --- prettier.config.mjs | Bin 248 -> 126 bytes 4 files changed, 17 deletions(-) diff --git a/.eslintrc.mjs b/.eslintrc.mjs index 23eb65752495dcfcc282928fed0696a52334ccb9..6e87e28351efb10fb55abebaa0d73b223d2949a9 100644 GIT binary patch literal 454 zcmaixK~BUl3`O^I3M=bIg;|CT_dqN6mkpw23hr9?JcK{e(930_5@s*Jr2xaU5d4ILPZWElk!fk?KVh49R02t)O2XTaB zTvttSG6mBlE&0I*O@>kW3%Pxa@tOaj{924J1M-%TNAgL2GzdjJQl0OMTNl>R%{blYN$0G#d^g-~^{k$A7fwC%!0tHQ?RBOTzSB>( zOgrp}H^Mh+1;w~m9~O(2W9iAD!S1m-_Ddo@GNMn7U%sbBpAL^fx4|p=Eb#Iw|L9-n zj@Ydp$mw^ihP+da|AXN50?%r+JW1aH0UR#HpVn@cFid}GsQNnK_AG(u= vZnO?`40{*TAI1n)*Li2fwdK2keNX-)vuV=?l@hV#Wvynk_!@S)p!44Woe-5e diff --git a/package-lock.json b/package-lock.json index a5f2cdb..89a2a99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -71,7 +71,6 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -1100,7 +1099,6 @@ "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -1111,7 +1109,6 @@ "integrity": "sha512-keKxkZMqnDicuvFoJbzrhbtdLSPhj/rZThDlKWCDbgXmUg0rEUFtRssDXKYmtXluZlIqiC5VqkCgRwzuyLHKHw==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -1172,7 +1169,6 @@ "integrity": "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.4", "@typescript-eslint/types": "8.46.4", @@ -1425,7 +1421,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1768,7 +1763,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", @@ -2377,7 +2371,6 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -4628,7 +4621,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -5300,7 +5292,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -5509,7 +5500,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5623,7 +5613,6 @@ "integrity": "sha512-Fl3ZdmJhDMJGcqrr342pPVrhugXdOcuNBRBauz4S7QGSRXbQy7y8q5QYJtgkcrG8XjY0EENSZeTk58c3m20FxA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@oxc-project/runtime": "0.96.0", "fdir": "^6.5.0", @@ -5718,7 +5707,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -5903,7 +5891,6 @@ "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "dev": true, "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -5939,7 +5926,6 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 2f040d7..64f0632 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,5 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.46.3", "vite": "npm:rolldown-vite@^7.2.2" - }, - "overrides": { - "vite": "npm:rolldown-vite@7.2.2" } } diff --git a/prettier.config.mjs b/prettier.config.mjs index e31406433d79059dc9ec8f24e5982ee248ab3509..ea15c0169aeb9ac663db275de872b37f1cefd32d 100644 GIT binary patch literal 126 zcmaFAdw*(0L4Hw*LUMjyafw24W?p(uYG7%8NveXaLP=3+sx=p?g4EnhpiEj~PBFSv mNl{{E4p6^yer|3eP>oV*v8fW8_L9V;@XVBw44|};H5UL6yDgvq literal 248 zcmaiuK?=e!6a{DPDN2tZxRS1V0#~l1##(4qObVV}9c#8yLc;qbGcWH~A=; z)0H&mL~rgGi0qiW$)<|Noqaz!ZCQE#H$+A)Kjuu(l@_V5J4g+szqNUEh2p6-BsSCw R?OEc$Udze Date: Wed, 19 Nov 2025 13:58:21 +0000 Subject: [PATCH 3/3] Add comprehensive folder structure with documentation and path aliases Co-authored-by: Vardhan-ysh <116566154+Vardhan-ysh@users.noreply.github.com> --- src/README.md | 106 +++++++++++++++++++++++++++++++++ src/components/README.md | 34 +++++++++++ src/components/common/index.ts | 2 + src/components/forms/index.ts | 2 + src/components/ui/index.ts | 2 + src/config/README.md | 69 +++++++++++++++++++++ src/config/index.ts | 3 + src/constants/README.md | 58 ++++++++++++++++++ src/constants/index.ts | 3 + src/features/README.md | 47 +++++++++++++++ src/features/index.ts | 2 + src/hooks/README.md | 38 ++++++++++++ src/hooks/index.ts | 2 + src/layouts/README.md | 58 ++++++++++++++++++ src/layouts/index.ts | 3 + src/pages/README.md | 31 ++++++++++ src/pages/index.ts | 2 + src/services/README.md | 49 +++++++++++++++ src/services/api/index.ts | 2 + src/services/index.ts | 2 + src/store/README.md | 56 +++++++++++++++++ src/store/index.ts | 2 + src/styles/README.md | 84 ++++++++++++++++++++++++++ src/styles/index.ts | 2 + src/types/README.md | 55 +++++++++++++++++ src/types/index.ts | 2 + src/utils/README.md | 63 ++++++++++++++++++++ src/utils/index.ts | 2 + tsconfig.app.json | 6 ++ vite.config.ts | 6 ++ 30 files changed, 793 insertions(+) create mode 100644 src/README.md create mode 100644 src/components/README.md create mode 100644 src/components/common/index.ts create mode 100644 src/components/forms/index.ts create mode 100644 src/components/ui/index.ts create mode 100644 src/config/README.md create mode 100644 src/config/index.ts create mode 100644 src/constants/README.md create mode 100644 src/constants/index.ts create mode 100644 src/features/README.md create mode 100644 src/features/index.ts create mode 100644 src/hooks/README.md create mode 100644 src/hooks/index.ts create mode 100644 src/layouts/README.md create mode 100644 src/layouts/index.ts create mode 100644 src/pages/README.md create mode 100644 src/pages/index.ts create mode 100644 src/services/README.md create mode 100644 src/services/api/index.ts create mode 100644 src/services/index.ts create mode 100644 src/store/README.md create mode 100644 src/store/index.ts create mode 100644 src/styles/README.md create mode 100644 src/styles/index.ts create mode 100644 src/types/README.md create mode 100644 src/types/index.ts create mode 100644 src/utils/README.md create mode 100644 src/utils/index.ts diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..a7c2e84 --- /dev/null +++ b/src/README.md @@ -0,0 +1,106 @@ +# Source Directory Structure + +This document describes the organization of the InterviewMint frontend source code. + +## Directory Overview + +``` +src/ +├── assets/ # Static assets (images, fonts, etc.) +├── components/ # Reusable UI components +│ ├── common/ # Shared components (Button, Input, Card) +│ ├── ui/ # UI-specific components (Modal, Dropdown) +│ └── forms/ # Form components +├── pages/ # Page-level components +├── features/ # Feature-specific modules +├── hooks/ # Custom React hooks +├── services/ # API services and external integrations +│ ├── api/ # API client and services +│ ├── storage/ # Storage utilities +│ └── analytics/ # Analytics services +├── store/ # Zustand state management +├── types/ # TypeScript type definitions +├── utils/ # Utility functions and helpers +├── constants/ # Application constants +├── config/ # Configuration files +├── layouts/ # Layout components +└── styles/ # Global styles and theme + +## Architecture Principles + +### Component Organization + +- **Components**: Reusable UI building blocks, organized by category +- **Pages**: Route-level components that compose features and components +- **Features**: Self-contained modules with their own components, hooks, and logic +- **Layouts**: Structural wrappers that define page templates + +### State Management + +- **Zustand** for global state management (auth, user preferences, etc.) +- **React Query** for server state (API data fetching and caching) +- **Local state** (useState) for component-specific state + +### Code Organization Best Practices + +1. **Colocation**: Keep related code close together +2. **Single Responsibility**: Each module should have one clear purpose +3. **Dependency Direction**: Dependencies should flow toward the domain layer +4. **Abstraction Levels**: Separate business logic from presentation + +### Import Conventions + +Use path aliases for cleaner imports: + +```tsx +// Bad +import { Button } from '../../../components/common/Button'; + +// Good +import { Button } from '@/components/common'; +``` + +Configure path aliases in `tsconfig.json`: + +```json +{ + "compilerOptions": { + "paths": { + "@/*": ["./src/*"] + } + } +} +``` + +## Technology Stack + +- **React 19** - UI library +- **TypeScript** - Type safety +- **Vite** - Build tool and dev server +- **React Query** - Server state management +- **Zustand** - Client state management +- **Axios** - HTTP client +- **Zod** - Schema validation + +## Getting Started + +1. Explore each directory's README.md for specific guidelines +2. Follow existing patterns when adding new code +3. Write tests for critical functionality +4. Keep components small and focused +5. Document complex logic + +## File Naming Conventions + +- **Components**: PascalCase (e.g., `UserCard.tsx`) +- **Hooks**: camelCase with `use` prefix (e.g., `useAuth.ts`) +- **Utils**: camelCase (e.g., `formatters.ts`) +- **Types**: PascalCase (e.g., `User.ts`) +- **Constants**: UPPER_SNAKE_CASE or camelCase files (e.g., `API_ENDPOINTS`) + +## Additional Resources + +- [React Best Practices](https://react.dev/learn) +- [TypeScript Handbook](https://www.typescriptlang.org/docs/) +- [Zustand Documentation](https://zustand-demo.pmnd.rs/) +- [React Query Documentation](https://tanstack.com/query/latest) diff --git a/src/components/README.md b/src/components/README.md new file mode 100644 index 0000000..d1627e5 --- /dev/null +++ b/src/components/README.md @@ -0,0 +1,34 @@ +# Components + +This directory contains reusable UI components organized by category. + +## Structure + +- **common/** - Shared components used across the application (e.g., Button, Input, Card) +- **ui/** - UI-specific components (e.g., Modal, Dropdown, Tooltip) +- **forms/** - Form-related components (e.g., FormInput, FormSelect, FormCheckbox) + +## Naming Convention + +- Use PascalCase for component names (e.g., `Button.tsx`, `UserCard.tsx`) +- Each component should have its own folder if it includes styles or tests +- Export components from index files for cleaner imports + +## Example + +```tsx +// components/common/Button/Button.tsx +export interface ButtonProps { + label: string; + onClick: () => void; + variant?: 'primary' | 'secondary'; +} + +export const Button: React.FC = ({ label, onClick, variant = 'primary' }) => { + return ( + + ); +}; +``` diff --git a/src/components/common/index.ts b/src/components/common/index.ts new file mode 100644 index 0000000..f34f5ec --- /dev/null +++ b/src/components/common/index.ts @@ -0,0 +1,2 @@ +// Export common components here +// Example: export { Button } from './Button'; diff --git a/src/components/forms/index.ts b/src/components/forms/index.ts new file mode 100644 index 0000000..55398d3 --- /dev/null +++ b/src/components/forms/index.ts @@ -0,0 +1,2 @@ +// Export form components here +// Example: export { FormInput } from './FormInput'; diff --git a/src/components/ui/index.ts b/src/components/ui/index.ts new file mode 100644 index 0000000..eb5ac78 --- /dev/null +++ b/src/components/ui/index.ts @@ -0,0 +1,2 @@ +// Export UI components here +// Example: export { Modal } from './Modal'; diff --git a/src/config/README.md b/src/config/README.md new file mode 100644 index 0000000..ad82612 --- /dev/null +++ b/src/config/README.md @@ -0,0 +1,69 @@ +# Config + +This directory contains application configuration files and setup. + +## Structure + +Configuration for libraries, services, and application setup. + +## Example + +```tsx +// config/axios.ts +import axios from 'axios'; +import { API_BASE_URL, API_TIMEOUT } from '@/constants'; + +export const axiosInstance = axios.create({ + baseURL: API_BASE_URL, + timeout: API_TIMEOUT, + headers: { + 'Content-Type': 'application/json', + }, +}); + +// Request interceptor +axiosInstance.interceptors.request.use( + (config) => { + const token = localStorage.getItem('token'); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + return config; + }, + (error) => Promise.reject(error) +); + +// Response interceptor +axiosInstance.interceptors.response.use( + (response) => response, + (error) => { + if (error.response?.status === 401) { + // Handle unauthorized + localStorage.removeItem('token'); + window.location.href = '/login'; + } + return Promise.reject(error); + } +); + +// config/reactQuery.ts +import { QueryClient } from '@tanstack/react-query'; + +export const queryClient = new QueryClient({ + defaultOptions: { + queries: { + staleTime: 1000 * 60 * 5, // 5 minutes + gcTime: 1000 * 60 * 30, // 30 minutes + retry: 1, + refetchOnWindowFocus: false, + }, + }, +}); +``` + +## Best Practices + +- Initialize third-party libraries here +- Keep configuration separate from constants +- Use environment variables for sensitive data +- Export configured instances, not raw configurations diff --git a/src/config/index.ts b/src/config/index.ts new file mode 100644 index 0000000..81e6142 --- /dev/null +++ b/src/config/index.ts @@ -0,0 +1,3 @@ +// Export configuration here +// Example: export { axiosInstance } from './axios'; +// Example: export { queryClient } from './reactQuery'; diff --git a/src/constants/README.md b/src/constants/README.md new file mode 100644 index 0000000..6eca193 --- /dev/null +++ b/src/constants/README.md @@ -0,0 +1,58 @@ +# Constants + +This directory contains application-wide constants and configuration values. + +## Structure + +Organize constants by domain or purpose. + +## Naming Convention + +- Use UPPER_SNAKE_CASE for constant names +- Group related constants in objects or enums + +## Example + +```tsx +// constants/api.ts +export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000/api'; +export const API_TIMEOUT = 30000; // 30 seconds + +export const API_ENDPOINTS = { + AUTH: { + LOGIN: '/auth/login', + LOGOUT: '/auth/logout', + REGISTER: '/auth/register', + REFRESH: '/auth/refresh', + }, + USERS: { + LIST: '/users', + DETAIL: (id: string) => `/users/${id}`, + UPDATE: (id: string) => `/users/${id}`, + DELETE: (id: string) => `/users/${id}`, + }, +} as const; + +// constants/routes.ts +export const ROUTES = { + HOME: '/', + LOGIN: '/login', + REGISTER: '/register', + DASHBOARD: '/dashboard', + PROFILE: '/profile', + SETTINGS: '/settings', +} as const; + +// constants/app.ts +export const APP_NAME = 'InterviewMint'; +export const APP_VERSION = '1.0.0'; +export const DEFAULT_PAGE_SIZE = 20; +export const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB +``` + +## Best Practices + +- Use environment variables for configuration that changes between environments +- Document the purpose of each constant +- Use `as const` for object constants to get literal types +- Keep magic numbers and strings as constants diff --git a/src/constants/index.ts b/src/constants/index.ts new file mode 100644 index 0000000..7a4f993 --- /dev/null +++ b/src/constants/index.ts @@ -0,0 +1,3 @@ +// Export constants here +// Example: export * from './api'; +// Example: export * from './routes'; diff --git a/src/features/README.md b/src/features/README.md new file mode 100644 index 0000000..4ef82d2 --- /dev/null +++ b/src/features/README.md @@ -0,0 +1,47 @@ +# Features + +This directory contains feature-specific modules organized by domain. + +## Structure + +Each feature should be self-contained with its own components, hooks, services, and types. + +``` +features/ + auth/ + components/ + hooks/ + services/ + types/ + index.ts + interviews/ + components/ + hooks/ + services/ + types/ + index.ts +``` + +## Naming Convention + +- Use lowercase for feature folder names (e.g., `auth`, `interviews`, `profile`) +- Each feature exports its public API through an index file + +## Example + +```tsx +// features/auth/hooks/useAuth.ts +export const useAuth = () => { + // Authentication logic +}; + +// features/auth/index.ts +export { useAuth } from './hooks/useAuth'; +export type { User } from './types'; +``` + +## Best Practices + +- Keep features independent and loosely coupled +- Share common logic through hooks and services +- Use feature flags for experimental features diff --git a/src/features/index.ts b/src/features/index.ts new file mode 100644 index 0000000..498d083 --- /dev/null +++ b/src/features/index.ts @@ -0,0 +1,2 @@ +// Export feature modules here +// Example: export * from './auth'; diff --git a/src/hooks/README.md b/src/hooks/README.md new file mode 100644 index 0000000..66ff104 --- /dev/null +++ b/src/hooks/README.md @@ -0,0 +1,38 @@ +# Hooks + +This directory contains custom React hooks that can be reused across the application. + +## Naming Convention + +- All hooks must start with `use` (e.g., `useAuth.ts`, `useDebounce.ts`) +- Use descriptive names that indicate the hook's purpose + +## Example + +```tsx +// hooks/useDebounce.ts +import { useEffect, useState } from 'react'; + +export const useDebounce = (value: T, delay: number): T => { + const [debouncedValue, setDebouncedValue] = useState(value); + + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + return () => { + clearTimeout(handler); + }; + }, [value, delay]); + + return debouncedValue; +}; +``` + +## Best Practices + +- Keep hooks focused on a single responsibility +- Document complex hooks with JSDoc comments +- Export hooks with named exports for better tree-shaking +- Test hooks using React Testing Library diff --git a/src/hooks/index.ts b/src/hooks/index.ts new file mode 100644 index 0000000..dadb82a --- /dev/null +++ b/src/hooks/index.ts @@ -0,0 +1,2 @@ +// Export custom hooks here +// Example: export { useDebounce } from './useDebounce'; diff --git a/src/layouts/README.md b/src/layouts/README.md new file mode 100644 index 0000000..f4f72a2 --- /dev/null +++ b/src/layouts/README.md @@ -0,0 +1,58 @@ +# Layouts + +This directory contains layout components that wrap pages and define the overall structure. + +## Structure + +Each layout defines a specific page structure (e.g., with/without sidebar, header, footer). + +## Naming Convention + +- Use PascalCase with Layout suffix (e.g., `MainLayout.tsx`, `AuthLayout.tsx`) + +## Example + +```tsx +// layouts/MainLayout.tsx +import { ReactNode } from 'react'; + +interface MainLayoutProps { + children: ReactNode; +} + +export const MainLayout: React.FC = ({ children }) => { + return ( +
+
+ +
+
+ {children} +
+
+ {/* Footer content */} +
+
+ ); +}; + +// layouts/AuthLayout.tsx +export const AuthLayout: React.FC<{ children: ReactNode }> = ({ children }) => { + return ( +
+
+ {children} +
+
+ ); +}; +``` + +## Best Practices + +- Keep layouts focused on structure, not business logic +- Use layouts with React Router for consistent page structure +- Make layouts responsive +- Consider creating layout variants for different viewports diff --git a/src/layouts/index.ts b/src/layouts/index.ts new file mode 100644 index 0000000..0697e9c --- /dev/null +++ b/src/layouts/index.ts @@ -0,0 +1,3 @@ +// Export layout components here +// Example: export { MainLayout } from './MainLayout'; +// Example: export { AuthLayout } from './AuthLayout'; diff --git a/src/pages/README.md b/src/pages/README.md new file mode 100644 index 0000000..63df762 --- /dev/null +++ b/src/pages/README.md @@ -0,0 +1,31 @@ +# Pages + +This directory contains page-level components that represent routes in the application. + +## Structure + +Each page should be in its own folder with related components and logic. + +## Naming Convention + +- Use PascalCase for page names (e.g., `HomePage.tsx`, `LoginPage.tsx`) +- Each page can have a folder containing the main page component and page-specific components + +## Example + +```tsx +// pages/Home/HomePage.tsx +export const HomePage: React.FC = () => { + return ( +
+

Welcome to InterviewMint

+
+ ); +}; +``` + +## Best Practices + +- Pages should be thin and delegate logic to hooks and services +- Keep page-specific components in the page folder +- Use feature modules for complex page logic diff --git a/src/pages/index.ts b/src/pages/index.ts new file mode 100644 index 0000000..d52f4a2 --- /dev/null +++ b/src/pages/index.ts @@ -0,0 +1,2 @@ +// Export page components here +// Example: export { HomePage } from './Home/HomePage'; diff --git a/src/services/README.md b/src/services/README.md new file mode 100644 index 0000000..5a05b34 --- /dev/null +++ b/src/services/README.md @@ -0,0 +1,49 @@ +# Services + +This directory contains API services and external integrations. + +## Structure + +- **api/** - API client configuration and services +- **storage/** - Local storage, session storage utilities +- **analytics/** - Analytics and tracking services + +## Naming Convention + +- Use descriptive names with Service suffix (e.g., `authService.ts`, `userService.ts`) +- Group related services in subdirectories + +## Example + +```tsx +// services/api/authService.ts +import axios from 'axios'; +import { API_BASE_URL } from '@/constants'; + +export const authService = { + login: async (email: string, password: string) => { + const response = await axios.post(`${API_BASE_URL}/auth/login`, { + email, + password, + }); + return response.data; + }, + + logout: async () => { + const response = await axios.post(`${API_BASE_URL}/auth/logout`); + return response.data; + }, + + getCurrentUser: async () => { + const response = await axios.get(`${API_BASE_URL}/auth/me`); + return response.data; + }, +}; +``` + +## Best Practices + +- Use axios interceptors for common logic (auth headers, error handling) +- Implement proper error handling and retry logic +- Use TypeScript for type-safe API calls +- Consider using React Query for data fetching diff --git a/src/services/api/index.ts b/src/services/api/index.ts new file mode 100644 index 0000000..78f6d23 --- /dev/null +++ b/src/services/api/index.ts @@ -0,0 +1,2 @@ +// Export API services here +// Example: export { authService } from './authService'; diff --git a/src/services/index.ts b/src/services/index.ts new file mode 100644 index 0000000..c1a3310 --- /dev/null +++ b/src/services/index.ts @@ -0,0 +1,2 @@ +// Export services here +export * from './api'; diff --git a/src/store/README.md b/src/store/README.md new file mode 100644 index 0000000..2618a31 --- /dev/null +++ b/src/store/README.md @@ -0,0 +1,56 @@ +# Store + +This directory contains Zustand state management stores. + +## Structure + +Each store should be in its own file and handle a specific domain of state. + +## Naming Convention + +- Use camelCase with Store suffix (e.g., `authStore.ts`, `userStore.ts`) +- Keep stores focused on a single domain + +## Example + +```tsx +// store/authStore.ts +import { create } from 'zustand'; + +interface User { + id: string; + email: string; + name: string; +} + +interface AuthState { + user: User | null; + token: string | null; + isAuthenticated: boolean; + login: (user: User, token: string) => void; + logout: () => void; +} + +export const useAuthStore = create((set) => ({ + user: null, + token: null, + isAuthenticated: false, + + login: (user, token) => { + localStorage.setItem('token', token); + set({ user, token, isAuthenticated: true }); + }, + + logout: () => { + localStorage.removeItem('token'); + set({ user: null, token: null, isAuthenticated: false }); + }, +})); +``` + +## Best Practices + +- Use Zustand's middleware for persistence and devtools +- Keep actions simple and delegate complex logic to services +- Use TypeScript for type-safe state management +- Consider using slices for large stores diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..f34f9d8 --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,2 @@ +// Export stores here +// Example: export { useAuthStore } from './authStore'; diff --git a/src/styles/README.md b/src/styles/README.md new file mode 100644 index 0000000..7419e01 --- /dev/null +++ b/src/styles/README.md @@ -0,0 +1,84 @@ +# Styles + +This directory contains global styles, themes, and CSS utilities. + +## Structure + +- **global.css** - Global styles and CSS resets +- **variables.css** - CSS custom properties (variables) +- **theme.ts** - Theme configuration (colors, typography, spacing) + +## Example + +```css +/* styles/variables.css */ +:root { + /* Colors */ + --color-primary: #3b82f6; + --color-secondary: #8b5cf6; + --color-success: #10b981; + --color-error: #ef4444; + --color-warning: #f59e0b; + + /* Typography */ + --font-family-base: 'Inter', system-ui, sans-serif; + --font-size-sm: 0.875rem; + --font-size-base: 1rem; + --font-size-lg: 1.125rem; + --font-size-xl: 1.25rem; + + /* Spacing */ + --spacing-xs: 0.25rem; + --spacing-sm: 0.5rem; + --spacing-md: 1rem; + --spacing-lg: 1.5rem; + --spacing-xl: 2rem; + + /* Border radius */ + --radius-sm: 0.25rem; + --radius-md: 0.375rem; + --radius-lg: 0.5rem; +} + +/* styles/global.css */ +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + font-family: var(--font-family-base); + font-size: var(--font-size-base); + line-height: 1.5; + color: var(--color-text); + background-color: var(--color-background); +} +``` + +```tsx +// styles/theme.ts +export const theme = { + colors: { + primary: '#3b82f6', + secondary: '#8b5cf6', + success: '#10b981', + error: '#ef4444', + warning: '#f59e0b', + }, + spacing: { + xs: '0.25rem', + sm: '0.5rem', + md: '1rem', + lg: '1.5rem', + xl: '2rem', + }, +} as const; +``` + +## Best Practices + +- Use CSS custom properties for theming +- Keep global styles minimal +- Consider using CSS modules or styled-components for component styles +- Maintain consistent design tokens diff --git a/src/styles/index.ts b/src/styles/index.ts new file mode 100644 index 0000000..2a1c846 --- /dev/null +++ b/src/styles/index.ts @@ -0,0 +1,2 @@ +// Export theme and style utilities here +// Example: export { theme } from './theme'; diff --git a/src/types/README.md b/src/types/README.md new file mode 100644 index 0000000..fdb588e --- /dev/null +++ b/src/types/README.md @@ -0,0 +1,55 @@ +# Types + +This directory contains shared TypeScript type definitions and interfaces. + +## Structure + +Organize types by domain or feature. + +## Naming Convention + +- Use PascalCase for type and interface names +- Use descriptive names that indicate the purpose +- Consider using `.d.ts` files for declaration files + +## Example + +```tsx +// types/user.ts +export interface User { + id: string; + email: string; + name: string; + role: UserRole; + createdAt: Date; + updatedAt: Date; +} + +export enum UserRole { + ADMIN = 'admin', + USER = 'user', + GUEST = 'guest', +} + +export type UserStatus = 'active' | 'inactive' | 'suspended'; + +// types/api.ts +export interface ApiResponse { + data: T; + message: string; + status: number; +} + +export interface PaginatedResponse extends ApiResponse { + total: number; + page: number; + pageSize: number; +} +``` + +## Best Practices + +- Keep types close to where they're used when they're feature-specific +- Use this directory for shared types used across multiple features +- Consider using Zod schemas for runtime validation +- Export types as named exports diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..80f30bb --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,2 @@ +// Export shared types here +// Example: export type { User, UserRole } from './user'; diff --git a/src/utils/README.md b/src/utils/README.md new file mode 100644 index 0000000..d0e1834 --- /dev/null +++ b/src/utils/README.md @@ -0,0 +1,63 @@ +# Utils + +This directory contains utility functions and helper modules. + +## Structure + +Organize utilities by category or functionality. + +## Naming Convention + +- Use camelCase for utility file names (e.g., `formatters.ts`, `validators.ts`) +- Use descriptive function names + +## Example + +```tsx +// utils/formatters.ts +export const formatDate = (date: Date): string => { + return new Intl.DateTimeFormat('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + }).format(date); +}; + +export const formatCurrency = (amount: number, currency = 'USD'): string => { + return new Intl.NumberFormat('en-US', { + style: 'currency', + currency, + }).format(amount); +}; + +// utils/validators.ts +export const isValidEmail = (email: string): boolean => { + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return emailRegex.test(email); +}; + +export const isValidUrl = (url: string): boolean => { + try { + new URL(url); + return true; + } catch { + return false; + } +}; + +// utils/string.ts +export const truncate = (str: string, length: number): string => { + return str.length > length ? str.slice(0, length) + '...' : str; +}; + +export const capitalize = (str: string): string => { + return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); +}; +``` + +## Best Practices + +- Keep functions pure when possible +- Write comprehensive unit tests for utilities +- Document complex utility functions with JSDoc +- Consider using libraries like lodash for common operations diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..50d1cc1 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,2 @@ +// Export utility functions here +// Example: export * from './formatters'; diff --git a/tsconfig.app.json b/tsconfig.app.json index a9b5a59..e6e8706 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -16,6 +16,12 @@ "noEmit": true, "jsx": "react-jsx", + /* Path Aliases */ + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, + /* Linting */ "strict": true, "noUnusedLocals": true, diff --git a/vite.config.ts b/vite.config.ts index a4f1bf2..cde9972 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,6 @@ import { defineConfig, loadEnv } from 'vite' import react from '@vitejs/plugin-react' +import path from 'path' // https://vite.dev/config/ export default defineConfig(({ mode }) => { @@ -13,6 +14,11 @@ export default defineConfig(({ mode }) => { }, }), ], + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, server: { port: Number(env.VITE_PORT) || 8080, },