xpeditis2.0/apps/frontend
David-Henri ARNAUD c03370e802 fix: resolve all test failures and TypeScript errors (100% test success)
 Fixed WebhookService Tests (2 tests failing → 100% passing)
- Increased timeout to 20s for retry test (handles 3 retries × 5s delays)
- Fixed signature verification test with correct 64-char hex signature
- All 7 webhook tests now passing

 Fixed Frontend TypeScript Errors
- Updated tsconfig.json with complete path aliases (@/types/*, @/hooks/*, @/utils/*, @/pages/*)
- Added explicit type annotations in useBookings.ts (prev: Set<string>)
- Fixed BookingFilters.tsx with proper type casts (s: BookingStatus)
- Fixed CarrierMonitoring.tsx with error callback types
- Zero TypeScript compilation errors

📊 Test Results
- Test Suites: 8 passed, 8 total (100%)
- Tests: 92 passed, 92 total (100%)
- Coverage: ~82% for Phase 3 services, 100% for domain entities

📝 Documentation Updated
- TEST_COVERAGE_REPORT.md: Updated to reflect 100% success rate
- IMPLEMENTATION_SUMMARY.md: Marked all issues as resolved

🎯 Phase 3 Status: COMPLETE
- All 13/13 features implemented
- All tests passing
- Production ready

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 14:48:50 +02:00
..
app feature phase 3 2025-10-13 13:58:39 +02:00
lib feature phase 3 2025-10-13 13:58:39 +02:00
src fix: resolve all test failures and TypeScript errors (100% test success) 2025-10-14 14:48:50 +02:00
.env.example first commit 2025-10-07 18:39:32 +02:00
.eslintrc.json first commit 2025-10-07 18:39:32 +02:00
.gitignore first commit 2025-10-07 18:39:32 +02:00
middleware.ts feature phase 2 2025-10-10 15:07:05 +02:00
next.config.js first commit 2025-10-07 18:39:32 +02:00
package-lock.json feature phase 3 2025-10-13 17:54:32 +02:00
package.json feature phase 3 2025-10-13 17:54:32 +02:00
postcss.config.js first commit 2025-10-07 18:39:32 +02:00
README.md first commit 2025-10-07 18:39:32 +02:00
tailwind.config.ts first commit 2025-10-07 18:39:32 +02:00
tsconfig.json fix: resolve all test failures and TypeScript errors (100% test success) 2025-10-14 14:48:50 +02:00

Xpeditis Frontend

Next.js 14-based frontend for the Xpeditis maritime freight booking platform.

🏗️ Tech Stack

  • Framework: Next.js 14 (App Router)
  • Language: TypeScript 5
  • Styling: Tailwind CSS + shadcn/ui
  • State Management: TanStack Query (React Query)
  • Forms: react-hook-form + zod
  • HTTP Client: axios
  • Icons: lucide-react
  • Testing: Jest + React Testing Library + Playwright

🚀 Quick Start

Install Dependencies

npm install

Setup Environment

cp .env.example .env

Default values work for local development!

Start Development Server

npm run dev

Open: http://localhost:3000

📝 Available Scripts

Development

  • npm run dev - Start development server (port 3000)
  • npm run build - Build for production
  • npm run start - Start production server
  • npm run lint - Lint code
  • npm test - Run tests
  • npm run test:watch - Run tests in watch mode
  • npm run test:e2e - Run Playwright E2E tests

📁 Project Structure

app/
├── layout.tsx          # Root layout
├── page.tsx           # Home page
├── globals.css        # Global styles
├── (routes)/          # Route groups
│   ├── search/       # Rate search
│   ├── bookings/     # Booking management
│   ├── dashboard/    # User dashboard
│   └── auth/         # Authentication
└── api/              # API routes (if needed)

components/
├── ui/               # shadcn/ui components
├── search/           # Search-specific components
├── bookings/         # Booking-specific components
└── shared/           # Shared components

lib/
├── api/              # API client & hooks
├── hooks/            # Custom React hooks
├── types/            # TypeScript types
├── utils.ts          # Utility functions
└── validators/       # Zod schemas

🎨 Styling

Tailwind CSS

Using Tailwind CSS with custom theme configuration.

CSS Variables (defined in globals.css):

  • --background, --foreground
  • --primary, --secondary
  • --muted, --accent
  • --destructive, --border
  • etc.

shadcn/ui Components

Pre-built accessible components:

  • Buttons, Cards, Dialogs
  • Forms, Inputs, Selects
  • Tables, Tabs, Dropdowns
  • And more...

Adding components:

npx shadcn-ui@latest add button
npx shadcn-ui@latest add card
# etc.

🔌 API Integration

API Client Setup

// lib/api/client.ts
import axios from 'axios';

const apiClient = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

export default apiClient;

React Query Hooks

// lib/api/rates.ts
import { useQuery } from '@tanstack/react-query';
import apiClient from './client';

export function useSearchRates(params: RateSearchParams) {
  return useQuery({
    queryKey: ['rates', params],
    queryFn: async () => {
      const { data } = await apiClient.post('/api/v1/rates/search', params);
      return data;
    },
  });
}

Usage in Components

// components/search/SearchResults.tsx
import { useSearchRates } from '@/lib/api/rates';

export function SearchResults({ params }: Props) {
  const { data, isLoading, error } = useSearchRates(params);

  if (isLoading) return <LoadingSkeleton />;
  if (error) return <ErrorMessage error={error} />;

  return <RatesList rates={data} />;
}

📋 Forms

Using react-hook-form + zod for type-safe form validation.

Example:

// lib/validators/search.ts
import { z } from 'zod';

export const searchSchema = z.object({
  origin: z.string().min(3, 'Invalid port code'),
  destination: z.string().min(3, 'Invalid port code'),
  containerType: z.enum(['20DRY', '40DRY', '40HC']),
  departureDate: z.string().datetime(),
});

export type SearchFormData = z.infer<typeof searchSchema>;
// components/search/SearchForm.tsx
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { searchSchema, SearchFormData } from '@/lib/validators/search';

export function SearchForm() {
  const { register, handleSubmit, formState: { errors } } = useForm<SearchFormData>({
    resolver: zodResolver(searchSchema),
  });

  const onSubmit = (data: SearchFormData) => {
    // Handle submission
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* Form fields */}
    </form>
  );
}

🧪 Testing

Unit Tests (Jest + React Testing Library)

npm test

Example:

// components/ui/Button.test.tsx
import { render, screen } from '@testing-library/react';
import { Button } from './Button';

describe('Button', () => {
  it('renders children', () => {
    render(<Button>Click me</Button>);
    expect(screen.getByText('Click me')).toBeInTheDocument();
  });
});

E2E Tests (Playwright)

npm run test:e2e

Example:

// e2e/search.spec.ts
import { test, expect } from '@playwright/test';

test('search for rates', async ({ page }) => {
  await page.goto('/search');
  await page.fill('[name="origin"]', 'NLRTM');
  await page.fill('[name="destination"]', 'CNSHA');
  await page.click('button[type="submit"]');
  await expect(page.locator('.rate-card')).toBeVisible();
});

🔒 Authentication

Authentication will be handled with:

  • JWT tokens from backend
  • NextAuth.js (optional)
  • Protected routes with middleware

Example (to be implemented):

// middleware.ts
export { default } from 'next-auth/middleware';

export const config = {
  matcher: ['/dashboard/:path*', '/bookings/:path*'],
};

📱 Responsive Design

Mobile-first approach with Tailwind breakpoints:

<div className="
  flex flex-col         // Mobile: column
  md:flex-row          // Tablet: row
  lg:gap-8             // Desktop: larger gap
  xl:max-w-7xl         // Extra large: max width
">
  {/* Content */}
</div>

Breakpoints:

  • sm: 640px
  • md: 768px
  • lg: 1024px
  • xl: 1280px
  • 2xl: 1536px

🎯 Performance

  • Code splitting: Automatic with Next.js App Router
  • Image optimization: Using Next.js <Image> component
  • React Query caching: Automatic caching of API responses
  • Bundle analysis: npm run build shows bundle sizes

🌐 Environment Variables

# API
NEXT_PUBLIC_API_URL=http://localhost:4000
NEXT_PUBLIC_API_PREFIX=api/v1

# Auth (NextAuth)
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-secret

# OAuth
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=

Note: Variables prefixed with NEXT_PUBLIC_ are exposed to the browser.

📖 Further Reading

🤝 Contributing

  1. Follow React/Next.js best practices
  2. Use TypeScript strict mode
  3. Write tests for components
  4. Ensure accessibility (WCAG 2.1 AA)
  5. Format with Prettier
  6. Lint with ESLint

📝 License

Proprietary - All rights reserved


Built with ❤️ using Next.js 14 and React 18