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
Complete Structure
Key Directories
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
Directory Purpose Files components/Reusable UI components ~60 files pages/Route-based page components 15 pages hooks/Custom React hooks for data fetching 11 hooks integrations/External service integrations Supabase lib/Core utilities and configurations 5 files context/Global state management AuthContext types/TypeScript definitions Custom types
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.
Dashboard Page
Shipments Page
// 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):
Page Route Access Description Index.tsx/Public Landing page SignIn.tsx/signinPublic Sign in page SignUp.tsx/signupPublic Registration page Dashboard.tsx/dashboardAdmin Analytics dashboard Shipments.tsx/shipmentsAuthenticated Shipment management Vehicles.tsx/vehiclesAdmin Vehicle management Transporters.tsx/transportersAdmin Transporter management Routes.tsx/routesAdmin Route management Packages.tsx/packagesAdmin Package management Materials.tsx/materialsAdmin Material management Reports.tsx/reportsAuthenticated Reports and analytics Settings.tsx/settingsAuthenticated User settings UserManagement.tsx/usersAdmin User administration InactivePage.tsx/inactiveSpecial Inactive account notice NotFound.tsx*Public 404 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):
Hook Purpose 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 :
File Purpose 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
Feature-Based
Composition
Container/Presenter
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
Heavy use of component composition for flexibility: < Card >
< CardHeader >
< CardTitle > Vehicles </ CardTitle >
</ CardHeader >
< CardContent >
< DataTable data = { vehicles } columns = { columns } />
</ CardContent >
</ Card >
Pages act as container components (data fetching, logic) while smaller components handle presentation. // Container (Page)
const VehiclesPage = () => {
const { data , isLoading } = useVehicles ();
return < VehicleList vehicles ={ data } loading ={ isLoading } />;
};
// Presenter (Component)
const VehicleList = ({ vehicles , loading }) => {
// Pure presentation logic
};
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
Colocation : Keep related files close together
Separation of Concerns : Business logic in hooks, UI in components
DRY (Don’t Repeat Yourself) : Shared logic in custom hooks
Type Safety : TypeScript everywhere with auto-generated types
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