Skip to main content

Overview

The Transport Logistics system follows a well-organized, feature-based directory structure that promotes maintainability and scalability. The codebase is structured around React best practices with clear separation of concerns.

Root Structure

transport-logistics/
├── src/                    # Source code
├── supabase/              # Database migrations and config
├── public/                # Static assets
├── package.json           # Dependencies and scripts
├── vite.config.ts         # Vite configuration
├── tsconfig.json          # TypeScript configuration
├── tailwind.config.ts     # Tailwind CSS configuration
└── README.md              # Project documentation

Source Directory Structure

src/
├── components/          # React components
│   ├── layouts/        # Layout components
│   ├── packages/       # Package-specific components
│   ├── ui/            # shadcn/ui components
│   └── ui-custom/     # Custom UI components
├── context/            # React Context providers
├── hooks/              # Custom React hooks
├── integrations/       # Third-party integrations
│   └── supabase/      # Supabase client and types
├── lib/               # Utility libraries
├── pages/             # Page components (routes)
├── styles/            # Global styles
├── types/             # TypeScript type definitions
├── utils/             # Utility functions
├── App.tsx            # Main application component
├── main.tsx           # Application entry point
└── index.css          # Global CSS

Detailed Directory Breakdown

/src/components/

Contains all React components organized by category.

components/layouts/

Layout components that provide consistent structure across pages.
// src/components/layouts/DashboardLayout.tsx
import { Navbar } from '@/components/ui-custom/Navbar';
import { Outlet } from 'react-router-dom';

export const DashboardLayout = () => {
  return (
    <div className="min-h-screen">
      <Navbar />
      <main className="container mx-auto p-6">
        <Outlet />
      </main>
    </div>
  );
};
Files:
  • DashboardLayout.tsx - Main dashboard layout with navbar and content area

components/packages/

Package-specific feature components. Files:
  • PackageForm.tsx - Form for creating and editing packages

components/ui/

shadcn/ui component library - beautifully designed, accessible components.
These components are copied into the project (not imported from a package) allowing full customization.
Key Components (~50 files):
  • accordion.tsx - Collapsible content sections
  • alert-dialog.tsx - Modal confirmation dialogs
  • button.tsx - Button component with variants
  • card.tsx - Content cards
  • dialog.tsx - Modal dialogs
  • dropdown-menu.tsx - Dropdown menus
  • form.tsx - Form components (integrates with react-hook-form)
  • input.tsx - Text input fields
  • select.tsx - Select dropdowns
  • table.tsx - Data tables
  • tabs.tsx - Tabbed interfaces
  • toast.tsx - Toast notifications (via Sonner)
  • And many more…

components/ui-custom/

Custom components built specifically for this application.
// src/components/ui-custom/DashboardCard.tsx
export const DashboardCard = ({ title, value, icon, trend }) => {
  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between">
        <CardTitle>{title}</CardTitle>
        {icon}
      </CardHeader>
      <CardContent>
        <div className="text-2xl font-bold">{value}</div>
        {trend && <p className="text-xs text-muted-foreground">{trend}</p>}
      </CardContent>
    </Card>
  );
};
Files:
  • DashboardCard.tsx - Dashboard metric cards
  • DataTable.tsx - Advanced data table with sorting, filtering, pagination
  • Navbar.tsx - Application navigation bar
  • PageTransition.tsx - Page transition animations

/src/pages/

Page components corresponding to routes in the application.
// src/pages/Dashboard.tsx
import { DashboardLayout } from '@/components/layouts/DashboardLayout';
import { useVehicles } from '@/hooks/use-vehicles';
import { useShipments } from '@/hooks/use-shipments';

export default function Dashboard() {
  const { data: vehicles } = useVehicles();
  const { data: shipments } = useShipments();
  
  // Dashboard logic and UI
}
Pages (15 files):
PageRouteAccessDescription
Index.tsx/PublicLanding page
SignIn.tsx/signinPublicSign in page
SignUp.tsx/signupPublicRegistration page
Dashboard.tsx/dashboardAdminAnalytics dashboard
Shipments.tsx/shipmentsAuthenticatedShipment management
Vehicles.tsx/vehiclesAdminVehicle management
Transporters.tsx/transportersAdminTransporter management
Routes.tsx/routesAdminRoute management
Packages.tsx/packagesAdminPackage management
Materials.tsx/materialsAdminMaterial management
Reports.tsx/reportsAuthenticatedReports and analytics
Settings.tsx/settingsAuthenticatedUser settings
UserManagement.tsx/usersAdminUser administration
InactivePage.tsx/inactiveSpecialInactive account notice
NotFound.tsx*Public404 page

/src/hooks/

Custom React hooks encapsulating business logic and data fetching.

Hook Pattern

All data fetching hooks follow a consistent pattern using TanStack Query for caching, background updates, and optimistic UI updates.
// src/hooks/use-vehicles.tsx
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { supabase } from '@/integrations/supabase/client';
import { Tables } from '@/integrations/supabase/types';

export type Vehicle = Tables<'vehicles'>;

export const useVehicles = () => {
  return useQuery({
    queryKey: ['vehicles'],
    queryFn: async () => {
      const { data, error } = await supabase
        .from('vehicles')
        .select('*, transporters(*)')
        .order('created_at', { ascending: false });
      
      if (error) throw error;
      return data;
    },
  });
};

export const useCreateVehicle = () => {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: async (vehicle: Omit<Vehicle, 'id' | 'created_at' | 'updated_at'>) => {
      const { data, error } = await supabase
        .from('vehicles')
        .insert(vehicle)
        .select()
        .single();
      
      if (error) throw error;
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['vehicles'] });
    },
  });
};
Available Hooks (11 files):
HookPurpose
use-vehicles.tsxVehicle CRUD operations
use-shipments.tsxShipment management
use-packages.tsxPackage operations
use-materials.tsxMaterial management
use-routes.tsxRoute management
use-transporters.tsxTransporter operations
use-users.tsxUser management (admin)
use-analytics.tsxDashboard analytics
use-report-shipments.tsReport generation
use-mobile.tsxMobile device detection
use-toast.tsToast notifications

/src/integrations/

Third-party service integrations.

integrations/supabase/

Supabase integration with auto-generated types.
// src/integrations/supabase/client.ts
import { createClient } from '@supabase/supabase-js';
import type { Database } from './types';

const SUPABASE_URL = "https://your-project.supabase.co";
const SUPABASE_PUBLISHABLE_KEY = "your-anon-key";

export const supabase = createClient<Database>(
  SUPABASE_URL,
  SUPABASE_PUBLISHABLE_KEY
);
Files:
  • client.ts - Supabase client instance
  • types.ts - Auto-generated TypeScript types from database schema (560 lines)
The types.ts file is automatically generated from the Supabase database schema, ensuring type safety across the entire application.

/src/lib/

Core utility libraries and configurations. Files:
FilePurpose
query-client.tsTanStack Query client configuration
query-keys.tsCentralized query key definitions
supabase.tsSupabase utility functions
utils.tsGeneral utility functions (cn, etc.)
data.tsStatic data and constants
// src/lib/query-client.ts
import { QueryClient } from '@tanstack/react-query';

export const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 60 * 1000, // 1 minute
      retry: 1,
      refetchOnWindowFocus: false,
    },
  },
});
// src/lib/utils.ts
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

/src/context/

React Context providers for global state.
// src/context/AuthContext.tsx
import { createContext, useContext, useEffect, useState } from 'react';
import { supabase } from '@/integrations/supabase/client';
import type { User } from '@supabase/supabase-js';

interface AuthContextType {
  user: User | null;
  loading: boolean;
  signOut: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    // Check active session
    supabase.auth.getSession().then(({ data: { session } }) => {
      setUser(session?.user ?? null);
      setLoading(false);
    });
    
    // Listen for auth changes
    const { data: { subscription } } = supabase.auth.onAuthStateChange(
      (_event, session) => {
        setUser(session?.user ?? null);
      }
    );
    
    return () => subscription.unsubscribe();
  }, []);
  
  const signOut = async () => {
    await supabase.auth.signOut();
  };
  
  return (
    <AuthContext.Provider value={{ user, loading, signOut }}>
      {children}
    </AuthContext.Provider>
  );
};

export const useAuth = () => {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};
Context Providers:
  • AuthContext.tsx - Authentication state and user profile

/src/types/

Custom TypeScript type definitions.
// src/types/index.ts
export interface ShipmentWithRelations extends Shipment {
  vehicles: Vehicle;
  materials: Material | null;
  routes: Route | null;
  transporters: Transporter;
}

export type ShipmentStatus = 'pending' | 'in-transit' | 'delivered' | 'cancelled';
export type VehicleStatus = 'available' | 'in-transit' | 'maintenance';
export type UserRole = 'admin' | 'user' | 'manager';

/src/utils/

Utility functions and helpers.
// Example utility functions
export const formatCurrency = (amount: number) => {
  return new Intl.NumberFormat('en-IN', {
    style: 'currency',
    currency: 'INR',
  }).format(amount);
};

export const formatDate = (date: string) => {
  return format(new Date(date), 'PPP');
};

Configuration Files

vite.config.ts

Vite build configuration with path aliases and plugins.
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc';
import path from 'path';

export default defineConfig({
  server: {
    host: '::',
    port: 8080,
  },
  plugins: [react()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
});

tsconfig.json

TypeScript configuration with path mapping.
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },
    "noImplicitAny": false,
    "skipLibCheck": true
  }
}

tailwind.config.ts

Tailwind CSS configuration with custom theme.
export default {
  content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {
      colors: {
        border: 'hsl(var(--border))',
        background: 'hsl(var(--background))',
        foreground: 'hsl(var(--foreground))',
        // ... custom color variables
      },
    },
  },
  plugins: [require('tailwindcss-animate')],
};

Application Entry Points

main.tsx

Application entry point that mounts React to the DOM.
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

App.tsx

Main application component with routing and providers.
import { QueryClientProvider } from '@tanstack/react-query';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { AuthProvider } from './context/AuthContext';
import { queryClient } from '@/lib/query-client';

const App = () => {
  return (
    <QueryClientProvider client={queryClient}>
      <TooltipProvider>
        <Toaster />
        <BrowserRouter>
          <AuthProvider>
            <AppRoutes />
          </AuthProvider>
        </BrowserRouter>
      </TooltipProvider>
    </QueryClientProvider>
  );
};
Key Features:
  • Lazy loading for code splitting
  • Protected routes with authentication
  • Admin-only routes
  • Loading states during route transitions

Architectural Patterns

Component Architecture

Components are organized by feature area (vehicles, shipments, packages) rather than by type (buttons, forms, modals).Benefits:
  • Easy to locate related code
  • Clear feature boundaries
  • Scalable structure

Data Flow

┌─────────────────────────────────────────────────┐
│                   User Action                   │
└────────────────────┬────────────────────────────┘


┌─────────────────────────────────────────────────┐
│          Component (Page/UI Component)          │
│         - Handles user interactions             │
└────────────────────┬────────────────────────────┘


┌─────────────────────────────────────────────────┐
│         Custom Hook (use-vehicles.tsx)          │
│      - TanStack Query mutation/query            │
└────────────────────┬────────────────────────────┘


┌─────────────────────────────────────────────────┐
│           Supabase Client (API call)            │
│        - Database operations with RLS           │
└────────────────────┬────────────────────────────┘


┌─────────────────────────────────────────────────┐
│              PostgreSQL Database                │
│           - Data persistence & RLS              │
└────────────────────┬────────────────────────────┘


┌─────────────────────────────────────────────────┐
│            Response flows back up               │
│      - Query cache updated automatically        │
│      - UI re-renders with new data             │
└─────────────────────────────────────────────────┘

State Management Strategy

Server State

Managed by TanStack Query
  • Automatic caching
  • Background refetching
  • Optimistic updates
  • Request deduplication

UI State

Managed by React useState/useReducer
  • Form state (react-hook-form)
  • Modal open/closed
  • Selected items
  • UI toggles

Global State

Managed by React Context
  • Authentication state
  • User profile
  • Theme preferences

Code Organization Principles

  1. Colocation: Keep related files close together
  2. Separation of Concerns: Business logic in hooks, UI in components
  3. DRY (Don’t Repeat Yourself): Shared logic in custom hooks
  4. Type Safety: TypeScript everywhere with auto-generated types
  5. Consistent Patterns: All hooks follow the same structure

Import Patterns

The project uses path aliases for clean imports:
// ✅ Good - Using path alias
import { Button } from '@/components/ui/button';
import { useVehicles } from '@/hooks/use-vehicles';
import { supabase } from '@/integrations/supabase/client';

// ❌ Bad - Relative paths
import { Button } from '../../../components/ui/button';
import { useVehicles } from '../../hooks/use-vehicles';

File Naming Conventions

  • Components: PascalCase (DashboardCard.tsx, Navbar.tsx)
  • Hooks: kebab-case with use- prefix (use-vehicles.tsx, use-toast.ts)
  • Utils: kebab-case (query-client.ts, utils.ts)
  • Pages: PascalCase (Dashboard.tsx, Shipments.tsx)
  • Types: kebab-case (index.ts)

Best Practices

Component Design

  • Small, focused components
  • Reusable UI components
  • Composition over inheritance
  • Props destructuring for clarity

Data Fetching

  • All queries in custom hooks
  • TanStack Query for caching
  • Loading and error states
  • Optimistic updates

Type Safety

  • Use auto-generated types
  • Avoid any type
  • Interface for props
  • Type inference where possible

Performance

  • Lazy load pages
  • Memoize expensive calculations
  • Use React Query cache
  • Optimize re-renders

Next Steps

Tech Stack

Learn about the technologies powering the application

Database Schema

Understand the database structure and relationships

Build docs developers (and LLMs) love