npm package: @pitamber/captify-core
Description: Core shared library for Captify applications
Latest version: 0.3.3

# @pitamber/captify-core

A comprehensive shared library providing reusable UI/UX components, utilities, hooks, and services for Captify applications. Built with Next.js 15, React 19, TypeScript, and Tailwind CSS using shadcn/ui components.

## Features

- 🎨 **Modern UI Components** - Built on shadcn/ui with Radix UI primitives
- 🔐 **Authentication** - NextAuth.js integration with AWS Cognito
- 📱 **Responsive Layouts** - ConsoleLayout with sidebar, toolbar, and navigation
- 🎯 **Type-Safe** - Full TypeScript support
- 🧩 **Modular Exports** - Import only what you need
- 📚 **Storybook** - Interactive component documentation
- ✅ **Testing** - Playwright for end-to-end testing
- 🎭 **Dark Mode** - Theme support with next-themes

## Table of Contents

- [Installation](#installation)
- [Quick Start](#quick-start)
- [Migration Guide](#migration-guide)
- [Project Structure](#project-structure)
- [Development](#development)
- [Testing the Library](#testing-the-library)
- [Available Components](#available-components)
- [Module Exports](#module-exports)
- [Usage Examples](#usage-examples)
- [Scripts](#scripts)
- [Changelog](#changelog)
- [Contributing](#contributing)

## Installation

Install from npm:

```bash
npm install @pitamber/captify-core
```

Or using pnpm:

```bash
pnpm add @pitamber/captify-core
```

Or using yarn:

```bash
yarn add @pitamber/captify-core
```

### For Local Development

If you're working on the library locally, you can link it:

```bash
npm install @pitamber/captify-core@file:../captify-core
```

### Peer Dependencies

Ensure your project has these peer dependencies installed:

```bash
npm install next@^14.0.0 || ^15.0.0 react@^18.0.0 || ^19.0.0 react-dom@^18.0.0 || ^19.0.0
```

## Quick Start

### Importing Components

**Important:** As of v0.2.0, you must import from specific module paths to avoid naming conflicts. As of v0.3.0, granular exports are available for even more precise imports.

```typescript
// ✅ Import from category modules (REQUIRED as of v0.2.0)
import { ConsoleLayout, Button } from "@pitamber/captify-core/components";
import { useBookmarkContext } from "@pitamber/captify-core/hooks";
import { cn } from "@pitamber/captify-core/utils";
import { ServiceItem } from "@pitamber/captify-core/types";
import { CognitoAdminService } from "@pitamber/captify-core/services";
import { acceptTermsAndConditions } from "@pitamber/captify-core/actions";

// ✅ Import from granular paths for tree-shaking (NEW in v0.3.0)
import { AppLauncher } from "@pitamber/captify-core/components/app-launcher";
import { useMobile } from "@pitamber/captify-core/hooks/use-mobile";
import { cn } from "@pitamber/captify-core/utils/cn";
import { CognitoAdminService } from "@pitamber/captify-core/services/cognito/services";

// ❌ Main entry point no longer exports everything (v0.2.0+)
// import { ConsoleLayout, Button } from "@pitamber/captify-core"; // This won't work
```

### Basic Setup

```tsx
import { ConsoleLayout } from "@pitamber/captify-core/components";
import { BookmarkProvider } from "@pitamber/captify-core/context";

export default function App() {
  return (
    <BookmarkProvider>
      <ConsoleLayout appName="My Application">{/* Your app content */}</ConsoleLayout>
    </BookmarkProvider>
  );
}
```

## Migration Guide

### Migrating from v0.1.x to v0.2.0

**Breaking Change:** The main entry point (`@pitamber/captify-core`) no longer re-exports all modules. You must use specific import paths.

#### Step 1: Update Your Imports

Search your codebase for imports from `@pitamber/captify-core` and update them:

```typescript
// ❌ OLD (v0.1.x) - Will not work in v0.2.0+
import {
  Button,
  ConsoleLayout,
  useBookmarkContext,
  cn
} from "@pitamber/captify-core";

// ✅ NEW (v0.2.0+) - Use specific module paths
import { Button, ConsoleLayout } from "@pitamber/captify-core/components";
import { useBookmarkContext } from "@pitamber/captify-core/hooks";
import { cn } from "@pitamber/captify-core/utils";
```

#### Step 2: Update Import Statements by Category

**Components:**
```typescript
// Before
import { Button, TopToolbar } from "@pitamber/captify-core";
// After
import { Button, TopToolbar } from "@pitamber/captify-core/components";
```

**Hooks:**
```typescript
// Before
import { useBookmarkContext } from "@pitamber/captify-core";
// After
import { useBookmarkContext } from "@pitamber/captify-core/hooks";
```

**Services:**
```typescript
// Before
import { CognitoAdminService } from "@pitamber/captify-core";
// After
import { CognitoAdminService } from "@pitamber/captify-core/services";
```

**Utilities:**
```typescript
// Before
import { cn } from "@pitamber/captify-core";
// After
import { cn } from "@pitamber/captify-core/utils";
```

#### Step 3: Verify Your Build

After updating imports, run your build to ensure everything works:

```bash
npm run build
# or
pnpm build
# or
yarn build
```

### Why This Change?

This breaking change was introduced to:
- ✅ Prevent naming conflicts between modules
- ✅ Enable better tree-shaking and smaller bundle sizes
- ✅ Make dependencies more explicit and easier to understand
- ✅ Improve IDE autocomplete and IntelliSense

## Project Structure

```
captify-core/
├── app/                    # Next.js app directory (for testing only)
│   ├── (authenticated)/    # Protected routes (dashboard, profile)
│   └── (unauthenticated)/  # Public routes (terms, login)
├── lib/                    # Library source code
│   ├── components/         # UI components
│   │   ├── ui/            # shadcn/ui components
│   │   ├── layouts/       # Layout components
│   │   ├── toolbars/      # Toolbar components
│   │   └── ...
│   ├── context/           # React Context providers
│   ├── hooks/             # Custom React hooks
│   ├── utils/             # Utility functions
│   ├── types/             # TypeScript types
│   ├── interfaces/        # TypeScript interfaces
│   ├── constants/         # Constants
│   ├── config/            # Configuration
│   ├── services/          # Service modules
│   ├── actions/           # Server actions
│   └── auth/              # Authentication config
├── stories/               # Storybook stories
├── tests/                 # Playwright tests
└── dist/                  # Build output (generated)
```

## Development

### Prerequisites

- Node.js 18+
- npm/pnpm/yarn

### Setup

1. Clone the repository
2. Install dependencies:

   ```bash
   npm install
   ```

3. Copy the environment template:

   ```bash
   cp .env.example .env
   ```

4. Configure your environment variables (see `.env.example`)

### Available Scripts

```bash
# Development
npm run dev                # Start Next.js dev server with Turbopack
npm run storybook          # Start Storybook on port 6006

# Building
npm run build              # Build library (TypeScript → dist/)
npm run build:next         # Build Next.js app
npm run type-check         # TypeScript check without emit
npm run validate           # Run lint + type-check

# Linting & Formatting
npm run lint               # Run ESLint
npm run lint:fix           # ESLint with auto-fix
npm run prettify           # Check Prettier formatting
npm run prettify:fix       # Auto-format with Prettier

# Testing
npm test                   # Run Playwright tests
npm run test:ui            # Playwright UI mode
npm run test:headed        # Playwright headed mode
npm run test:debug         # Playwright debug mode
```

## Testing the Library

The `app/` directory contains a test application to demonstrate and test library components:

### Running the Test App

1. Set up your environment variables in `.env` (see `.env.example`)
2. Start the development server:
   ```bash
   npm run dev
   ```
3. Open [http://localhost:3000](http://localhost:3000)

### Test Pages

- **Terms & Conditions** (`/`) - Landing page with terms acceptance modal
- **Profile** (`/profile`) - User profile page (requires auth)

These pages demonstrate:

- Authentication flow with AWS Cognito
- Terms and conditions acceptance
- Protected routes with middleware
- Layout components (ConsoleLayout, AppSidebar, TopToolbar)
- Theme switching

### Using Storybook

Storybook provides interactive documentation for all components:

```bash
npm run storybook
```

Open [http://localhost:6006](http://localhost:6006) to explore components.

## Available Components

### Layout Components

- **ConsoleLayout** - Main application layout wrapper
- **AppHeader** - Application header
- **AppSidebar** - Collapsible sidebar with navigation
- **AppServicesBar** - Quick access services bar
- **TopToolbar** - Top toolbar with search, notifications, profile

### UI Components (shadcn/ui)

- **Avatar** - User avatar display
- **Badge** - Status and notification badges
- **Button** - Various button variants
- **Card** - Content cards
- **Checkbox** - Form checkbox input
- **Dialog** - Modal dialogs
- **Dropdown Menu** - Context menus
- **Input** - Text input fields
- **Separator** - Visual dividers
- **Sheet** - Slide-out panels
- **Skeleton** - Loading placeholders
- **Table** - Data tables
- **Tooltip** - Hover tooltips

### Feature Components

- **Breadcrumb** - Navigation breadcrumbs
- **Notifications** - Notification center
- **AppLauncher** - Application launcher grid
- **TermsAndConditionsModal** - Terms acceptance modal
- **GenericNotFoundUI** - 404 error page

### Context Providers

- **BookmarkProvider** - Bookmark management
- **ThemeProvider** - Dark/light theme switching

### Hooks

- **useBookmarkContext** - Access bookmark state
- **useIsMobile** - Responsive breakpoint detection

### Services

- **AWS Services** - S3, DynamoDB, Cognito integrations

## Usage Examples

### Using ConsoleLayout

```tsx
import { ConsoleLayout } from "@pitamber/captify-core/components";
import { MenuItem } from "@pitamber/captify-core/types";

const menuItems: MenuItem[] = [
  { title: "Dashboard", url: "/dashboard", icon: "Home" },
  { title: "Settings", url: "/settings", icon: "Settings" },
];

export default function MyApp() {
  return (
    <ConsoleLayout appName="My Application" menuItems={menuItems}>
      <main>{/* Your content */}</main>
    </ConsoleLayout>
  );
}
```

### Using Bookmark Context

```tsx
import { useBookmarkContext } from '@pitamber/captify-core/hooks';

function MyComponent() {
  const {
    bookmarkedServices,
    addBookmark,
    removeBookmark
  } = useBookmarkContext();

  const handleBookmark = (service: ServiceItem) => {
    if (bookmarkedServices.find(s => s.id === service.id)) {
      removeBookmark(service.id);
    } else {
      addBookmark(service);
    }
  };

  return (
    // Your component JSX
  );
}
```

### Using Utility Functions

```tsx
import { cn } from "@pitamber/captify-core/utils";

function MyComponent() {
  return (
    <div className={cn("base-styles", condition && "conditional-styles", className)}>Content</div>
  );
}
```

## Module Exports

**v0.2.0+**: The library uses granular exports to prevent naming conflicts and enable better tree-shaking. You **must** import from specific module paths.

**v0.3.0+**: Enhanced with even more granular exports for maximum flexibility and optimal tree-shaking.

### Available Module Paths

#### Category-Level Exports (v0.2.0+)

```typescript
// Components - All UI/UX components
import { Button, ConsoleLayout, AppSidebar, TopToolbar } from '@pitamber/captify-core/components';

// Hooks - Custom React hooks
import { useBookmarkContext, useMobile } from '@pitamber/captify-core/hooks';

// Utils - Utility functions
import { cn, formatDate } from '@pitamber/captify-core/utils';

// Types - TypeScript type definitions
import { ServiceItem, MenuItem } from '@pitamber/captify-core/types';

// Interfaces - TypeScript interfaces
import { NotificationProps, LayoutProps } from '@pitamber/captify-core/interfaces';

// Services - AWS service integrations
import { CognitoAdminService, DynamoDBService, S3Service } from '@pitamber/captify-core/services';

// Actions - Server actions
import { acceptTermsAndConditions, cognitoSignOut } from '@pitamber/captify-core/actions';

// Auth - NextAuth configuration
import { auth, signIn, signOut } from '@pitamber/captify-core/auth';

// Context - React Context providers
import { BookmarkProvider, ThemeProvider } from '@pitamber/captify-core/context';

// Providers - React providers
import { AuthSessionProvider } from '@pitamber/captify-core/providers';

// Config - Configuration files
import { routeConfig } from '@pitamber/captify-core/config';

// Constants - Application constants
import { APP_LAUNCHER_CONSTANTS } from '@pitamber/captify-core/constants';
```

#### Granular Exports (v0.3.0+)

For even better tree-shaking and more precise imports:

```typescript
// ===== COMPONENTS =====
// Specific component groups
import { AppLauncher } from '@pitamber/captify-core/components/app-launcher';
import { BreadcrumbComponent } from '@pitamber/captify-core/components/breadcrumb';
import { ConsoleLayout } from '@pitamber/captify-core/components/console-layout';
import { ErrorBoundary } from '@pitamber/captify-core/components/error-boundary';
import { AppLayout, AppHeader, AppSidebar } from '@pitamber/captify-core/components/layouts';
import { LoadingSkeleton } from '@pitamber/captify-core/components/loading-skeleton';
import { GenericNotFoundUI } from '@pitamber/captify-core/components/not-found';
import { Notifications } from '@pitamber/captify-core/components/notifications';
import { FeaturedServiceNavItem } from '@pitamber/captify-core/components/services';
import { TermsAndConditionsModal } from '@pitamber/captify-core/components/terms-and-agreements';
import { TopToolbar, TopRightToolbar } from '@pitamber/captify-core/components/toolbars';
import { Button, Card, Dialog, Input } from '@pitamber/captify-core/components/ui';

// ===== HOOKS =====
import { useMobile } from '@pitamber/captify-core/hooks/use-mobile';
import { useNotifications } from '@pitamber/captify-core/hooks/use-notifications';

// ===== UTILS =====
import { cn } from '@pitamber/captify-core/utils/cn';
import { formatDate } from '@pitamber/captify-core/utils/date';
import { invariant } from '@pitamber/captify-core/utils/invariant';
import { capitalize } from '@pitamber/captify-core/utils/string';

// ===== CONTEXT =====
import { BookmarkProvider } from '@pitamber/captify-core/context/bookmark';
import { ThemeProvider } from '@pitamber/captify-core/context/theme';

// ===== ACTIONS =====
import { cognitoSignOut } from '@pitamber/captify-core/actions/auth';
import { acceptTermsAndConditions } from '@pitamber/captify-core/actions/terms-and-conditions';

// ===== AUTH =====
import { refreshCognitoTokens } from '@pitamber/captify-core/auth/refresh-token';

// ===== CONFIG =====
import { routeConfig } from '@pitamber/captify-core/config/route-config';

// ===== CONSTANTS =====
import { APP_LAUNCHER_CONSTANTS } from '@pitamber/captify-core/constants/app-launcher';
import { PROFILE_DROPDOWN_ITEMS } from '@pitamber/captify-core/constants/profile-dropdown';
import { TABLES } from '@pitamber/captify-core/constants/tables';

// ===== INTERFACES =====
import { AppLauncherProps } from '@pitamber/captify-core/interfaces/app-launcher';
import { BreadcrumbProps } from '@pitamber/captify-core/interfaces/breadcrumb';
import { LayoutProps } from '@pitamber/captify-core/interfaces/layout-props';
import { NavConfigProps } from '@pitamber/captify-core/interfaces/nav-config-props';
import { NotificationProps } from '@pitamber/captify-core/interfaces/notification-props';
import { RouteItem } from '@pitamber/captify-core/interfaces/route-item';
import { SearchProps } from '@pitamber/captify-core/interfaces/search';
import { ServiceItem } from '@pitamber/captify-core/interfaces/service';
import { SidebarProps } from '@pitamber/captify-core/interfaces/sidebar-props';
import { ToolbarProps } from '@pitamber/captify-core/interfaces/toolbar-props';

// ===== PROVIDERS =====
import { AuthSessionProvider } from '@pitamber/captify-core/providers/auth-session';

// ===== SERVICES =====
// Chat Service
import { ChatService } from '@pitamber/captify-core/services/chat';
import { CHAT_CONSTANTS } from '@pitamber/captify-core/services/chat/constants';
import { ChatError } from '@pitamber/captify-core/services/chat/errors';
import { ChatMessage } from '@pitamber/captify-core/services/chat/interfaces';
import { ChatService as ChatServiceClass } from '@pitamber/captify-core/services/chat/services';
import { validateChatMessage } from '@pitamber/captify-core/services/chat/utilities';

// Cognito Service
import { CognitoAdminService } from '@pitamber/captify-core/services/cognito';
import { COGNITO_CONSTANTS } from '@pitamber/captify-core/services/cognito/constants';
import { CognitoError } from '@pitamber/captify-core/services/cognito/errors';
import { CognitoUser } from '@pitamber/captify-core/services/cognito/interfaces';
import { CognitoAdminService as CognitoAdmin } from '@pitamber/captify-core/services/cognito/services';

// DynamoDB Service
import { DynamoDBService } from '@pitamber/captify-core/services/dynamodb';
import { DYNAMODB_CONSTANTS } from '@pitamber/captify-core/services/dynamodb/constants';
import { DynamoDBError } from '@pitamber/captify-core/services/dynamodb/errors';
import { DynamoDBConfig } from '@pitamber/captify-core/services/dynamodb/interfaces';
import { DynamoDBService as DynamoDBClient } from '@pitamber/captify-core/services/dynamodb/services';

// S3 Service
import { S3Service } from '@pitamber/captify-core/services/s3';
import { S3_CONSTANTS } from '@pitamber/captify-core/services/s3/constants';
import { S3Error } from '@pitamber/captify-core/services/s3/errors';
import { S3Config } from '@pitamber/captify-core/services/s3/interfaces';
import { S3Service as S3Client } from '@pitamber/captify-core/services/s3/services';

// Shared Service Utilities
import { BaseAwsService } from '@pitamber/captify-core/services/shared';
import { AWS_ERROR_KIND } from '@pitamber/captify-core/services/shared/constants';
import { BaseAwsError } from '@pitamber/captify-core/services/shared/errors';
import { Logger } from '@pitamber/captify-core/services/shared/interfaces';
import { ConsoleLogger } from '@pitamber/captify-core/services/shared/logger';
import { BaseAwsService as AwsService } from '@pitamber/captify-core/services/shared/services';
```

### Why Granular Exports?

✅ **No naming conflicts** - Isolated modules prevent name collisions
✅ **Better tree-shaking** - Only bundle what you actually use
✅ **Clearer dependencies** - Explicit about what you're importing
✅ **Improved IDE autocomplete** - More precise suggestions
✅ **Optimal bundle size** - Import exactly what you need (v0.3.0)
✅ **Flexible imports** - Choose between category or granular imports (v0.3.0)

## Authentication

The library includes NextAuth.js integration with AWS Cognito:

### Setup

1. Configure environment variables (see `.env.example`)
2. The auth config is in `lib/auth/index.ts`
3. Middleware protects routes automatically

### Usage in Your App

```tsx
import { auth } from "@pitamber/captify-core/auth";

// Server component
export default async function Page() {
  const session = await auth();

  if (!session) {
    return <div>Not authenticated</div>;
  }

  return <div>Hello {session.user.name}</div>;
}
```

## Adding New Components

1. Create component in appropriate `lib/` subdirectory:

   ```bash
   lib/components/my-component/
   ├── my-component.tsx
   └── index.ts
   ```

2. Export from directory's `index.ts`:

   ```typescript
   export * from "./my-component";
   ```

3. Export from parent module:

   ```typescript
   // lib/components/index.ts
   export * from "./my-component";
   ```

4. Create Storybook story (optional):
   ```bash
   stories/components/MyComponent.stories.tsx
   ```

## Code Quality

### ESLint Rules

- Strict mode enabled
- `no-console: error` (use `// eslint-disable-next-line no-console` for intentional logs)
- `no-undef: error`
- Unused vars allowed with `_` prefix
- `lib/components/ui/**` ignored (external shadcn components)

### Pre-commit Hooks

Husky runs lint-staged on commit to auto-fix:

- ESLint issues
- Prettier formatting

## TypeScript

Two TypeScript configurations:

- `tsconfig.json` - Next.js development
- `tsconfig.build.json` - Library build (targets `lib/`, outputs `dist/`)

Path aliases:

- `@/*` → project root
- `@pitamber/captify-core` → `lib/`

## Styling

- **Tailwind CSS** with custom configuration
- **CSS Variables** for theming
- **Dark Mode** support via next-themes
- **shadcn/ui** style: "new-york", base color: "neutral"

## Browser Support

- Modern browsers (Chrome, Firefox, Safari, Edge)
- ES2020+ features

## Changelog

### v0.3.0 (2025-01-26)

**New Features:**
- ✨ **100+ Granular Export Paths** - Ultra-precise imports for optimal tree-shaking
- ✨ **Component-Level Exports** - Import specific components directly
  - `@pitamber/captify-core/components/app-launcher`
  - `@pitamber/captify-core/components/console-layout`
  - `@pitamber/captify-core/components/breadcrumb`
  - And many more!
- ✨ **Hook-Level Exports** - Direct hook imports
  - `@pitamber/captify-core/hooks/use-mobile`
  - `@pitamber/captify-core/hooks/use-notifications`
- ✨ **Utility-Level Exports** - Import individual utilities
  - `@pitamber/captify-core/utils/cn`
  - `@pitamber/captify-core/utils/date`
  - `@pitamber/captify-core/utils/string`
- ✨ **Service Submodule Exports** - Granular service imports
  - `@pitamber/captify-core/services/cognito/services`
  - `@pitamber/captify-core/services/cognito/constants`
  - `@pitamber/captify-core/services/cognito/errors`
  - Similar structure for S3, DynamoDB, and Chat services
- ✨ **Interface-Level Exports** - Import specific interfaces
  - `@pitamber/captify-core/interfaces/app-launcher`
  - `@pitamber/captify-core/interfaces/breadcrumb`
  - And all other interfaces
- ✨ **Constant-Level Exports** - Direct constant imports
  - `@pitamber/captify-core/constants/app-launcher`
  - `@pitamber/captify-core/constants/profile-dropdown`
  - `@pitamber/captify-core/constants/tables`

**Improvements:**
- 🎯 **Maximum Tree-Shaking** - Import exactly what you need, nothing more
- 🎯 **Smaller Bundle Sizes** - Granular imports reduce final bundle size
- 🎯 **Better Developer Experience** - More intuitive import paths
- 🎯 **Flexible Import Strategy** - Choose between category or granular imports
- 📝 **Comprehensive Documentation** - Full list of all 100+ export paths
- 🔧 **UI Components Index** - Added index.ts for all shadcn/ui components
- 🔧 **Constants Export** - Added missing tables constants export

**Technical:**
- 📦 Published to npm registry as public package
- ✅ All validation and build checks pass
- ✅ Path aliases properly converted to relative imports

### v0.2.0 (2025-01-26)

**Breaking Changes:**
- 🚨 Main entry point (`@pitamber/captify-core`) no longer re-exports all modules
- All imports must now use specific module paths (e.g., `@pitamber/captify-core/components`)
- See [Migration Guide](#migration-guide) for upgrade instructions

**New Features:**
- ✨ Granular exports to prevent naming conflicts
- ✨ Added complete exports for all services (Cognito, DynamoDB, S3, Chat)
- ✨ Added terms-and-conditions actions export
- ✨ Added utilities exports for all service modules

**Improvements:**
- 🎯 Better tree-shaking support - only bundle what you use
- 🎯 Clearer dependency management
- 🎯 Improved IDE autocomplete and IntelliSense
- 📝 Updated documentation with comprehensive import examples

**Bug Fixes:**
- 🐛 Fixed missing exports in lib/actions/index.ts
- 🐛 Fixed missing exports in lib/services/cognito/index.ts
- 🐛 Fixed missing exports in lib/services/dynamodb/index.ts

### v0.1.20 (Previous)

- Initial stable release with all core components and services

## Contributing

1. Create a feature branch
2. Make your changes
3. Run `npm run validate` to ensure quality
4. Commit your changes (pre-commit hooks will run)
5. Submit a pull request

## License

MIT

## Support

For issues and questions, please use the GitHub issue tracker.

## Related Projects

- [Next.js](https://nextjs.org/)
- [React](https://react.dev/)
- [shadcn/ui](https://ui.shadcn.com/)
- [Tailwind CSS](https://tailwindcss.com/)
- [NextAuth.js](https://next-auth.js.org/)