📦 Parcel Delivery Client
A modern, modular, and secure web application for managing parcel deliveries. Built with React, TypeScript, shadcn/ui, RTK Query, and Recharts for analytics.
Live Demo: Parcel Delivery Client.
GitHub Repository (Frontend): Parcel Delivery Client.
GitHub Repository (Backend): Parcel Delivery Server.
🧱 Features
- Authentication: Email/password login, JWT, OTP verification
- Role-based Access to dashboard: Sender, Receiver, Admin, Super Admin, Delivery Personnel
- Manage users, parcels, and deliveries
- Parcel Lifecycle: Request, Approve, Picked, Dispatch, In Transit, Deliver, Block, Cancel, Flagged
- Real-time Tracking: Track parcels by tracking ID
- Status Analytics: Bar and Pie charts for delivery status, parcel type, shipping type, and trends
- Responsive UI: Modern design with shadcn/ui and Tailwind CSS
- Coupon Support: Admins can create and manage coupons
- Notifications: Email for OTP verification
- Contact email using Emailjs
- Global Error Handling: User-friendly error messages
🧩 Tech Stack
- React + Vite — Frontend framework
- TypeScript — Type safety
- shadcn/ui — Modern UI components
- Tailwind CSS — Utility-first styling
- RTK Query — Data fetching and caching
- Recharts — Analytics and charts
- Sonner — Toast notifications
- React Hook Form + Zod — Forms and validation
- Lucide Icons — Icon set
- Emailjs for email receiving
🛠️ Getting Started
# 1. Clone the repo
git clone https://github.com/faisal-akbar/b5b6-frontend.git
cd b5b6-frontend
# 2. Install dependencies
npm install
# 3. Configure environment
cp .env.example .env
# 4. Update .env with your MongoDB URI, nodemailer credentials, redis credentials, etc.
VITE_BASE_URL=http://localhost:5000/api/v1
VITE_EMAILJS_SERVICE_ID=your_service_id
VITE_EMAILJS_TEMPLATE_ID=template_id
VITE_EMAILJS_PUBLIC_ID=your_public_id
# 5. Run locally
npm run dev🔐 Email and password for testing dummy users:
// SUPER_ADMIN
email: "super@gmail.com",
password: "12345678"
// SENDER
email: "john.sender@parcel.com",
password: "sender123"
// RECEIVER
email: "bob.receiver@parcel.com",
password: "receiver123",
// ADMIN
email: "admin@parcel.com",
password: "Ph@12345678"
// Sample Id's for delivery personnel
"68ad6b75b010e0e1a1c78d20"
"68ad6b74b010e0e1a1c78d1d"📦 Public Parcel Status
Use this below sample tracking id:
TRK-20250826-404197
📦 Sample Coupon
IK5QY5NLTU56CKCZ
📁 Folder Structure
.
├── README.md
├── components.json
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.tsx
│ ├── assets
│ │ ├── icons
│ │ │ └── Logo.tsx
│ │ ├── images
│ │ │ ├── parcel-login.jpg
│ │ │ └── parcel-register.jpg
│ │ └── react.svg
│ ├── components
│ │ ├── DeleteConformation.tsx
│ │ ├── Error.tsx
│ │ ├── ErrorBoundary.tsx
│ │ ├── Information.tsx
│ │ ├── Loading.tsx
│ │ ├── NotFound.tsx
│ │ ├── app-sidebar.tsx
│ │ ├── layout
│ │ │ ├── CommonLayout.tsx
│ │ │ ├── DashboardLayout.tsx
│ │ │ ├── Footer.tsx
│ │ │ ├── ModeToggle.tsx
│ │ │ └── Navbar.tsx
│ │ ├── modules
│ │ │ ├── about
│ │ │ │ ├── AboutFeatures.tsx
│ │ │ │ ├── AboutHero.tsx
│ │ │ │ └── AboutJourney.tsx
│ │ │ ├── admin
│ │ │ │ ├── parcels
│ │ │ │ │ ├── AdminParcelDetails.tsx
│ │ │ │ │ ├── AdminParcelModal.tsx
│ │ │ │ │ ├── AdminParcelTimeLine.tsx
│ │ │ │ │ ├── AdminParcelsTable.tsx
│ │ │ │ │ └── analytics
│ │ │ │ │ ├── DeliveryStatysBarChart.tsx
│ │ │ │ │ ├── OverViewCards.tsx
│ │ │ │ │ ├── ParcelsCharts.tsx
│ │ │ │ │ ├── ShipmentBarChart.tsx
│ │ │ │ │ ├── ShippingTypeChart.tsx
│ │ │ │ │ └── TypePieChart.tsx
│ │ │ │ └── users
│ │ │ │ ├── CreateStuff.tsx
│ │ │ │ └── UsersTable.tsx
│ │ │ ├── authentication
│ │ │ │ ├── LoginForm.tsx
│ │ │ │ └── RegisterForm.tsx
│ │ │ ├── contact
│ │ │ │ ├── ContactHero.tsx
│ │ │ │ └── contactForm.tsx
│ │ │ ├── faq
│ │ │ │ ├── FaqContact.tsx
│ │ │ │ ├── FaqHero.tsx
│ │ │ │ └── FaqSection.tsx
│ │ │ ├── features
│ │ │ │ ├── FeaturesBenefit.tsx
│ │ │ │ ├── FeaturesCTA.tsx
│ │ │ │ ├── FeaturesGrid.tsx
│ │ │ │ └── FeaturesHero.tsx
│ │ │ ├── home
│ │ │ │ ├── Feature.tsx
│ │ │ │ ├── Hero.tsx
│ │ │ │ ├── HomeAbout.tsx
│ │ │ │ ├── HomeCTA.tsx
│ │ │ │ ├── HomeFaq.tsx
│ │ │ │ └── HomeTestimonials.tsx
│ │ │ ├── receiver
│ │ │ │ ├── ReceiverHistoryParcelTable.tsx
│ │ │ │ └── ReceiverIncomingParcelTable.tsx
│ │ │ ├── sender
│ │ │ │ ├── SendParcelModal.tsx
│ │ │ │ ├── SenderParcelTable.tsx
│ │ │ │ ├── StatusDetails.tsx
│ │ │ │ └── StatusTimeLine.tsx
│ │ │ ├── testimonials
│ │ │ │ ├── TestimonialsCTA.tsx
│ │ │ │ └── TestimonialsSection.tsx
│ │ │ └── trackParcel
│ │ │ ├── HelpSection.tsx
│ │ │ ├── ParcelDetails.tsx
│ │ │ ├── TimeLine.tsx
│ │ │ ├── Track.tsx
│ │ │ ├── TrackParcelForm.tsx
│ │ │ └── TrackParcelHero.tsx
│ │ └── ui
│ │ ├── Password.tsx
│ │ ├── accordion.tsx
│ │ ├── alert-dialog.tsx
│ │ ├── avatar.tsx
│ │ ├── badge.tsx
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── chart.tsx
│ │ ├── checkbox.tsx
│ │ ├── dialog.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── form.tsx
│ │ ├── input-otp.tsx
│ │ ├── input.tsx
│ │ ├── label.tsx
│ │ ├── nav-user.tsx
│ │ ├── navigation-menu.tsx
│ │ ├── pagination.tsx
│ │ ├── popover.tsx
│ │ ├── select.tsx
│ │ ├── separator.tsx
│ │ ├── shadcn-io
│ │ │ └── spinner
│ │ │ └── index.tsx
│ │ ├── sheet.tsx
│ │ ├── sidebar.tsx
│ │ ├── skeleton.tsx
│ │ ├── sonner.tsx
│ │ ├── table.tsx
│ │ ├── textarea.tsx
│ │ └── tooltip.tsx
│ ├── config
│ │ └── index.ts
│ ├── context
│ │ └── theme-context.ts
│ ├── hooks
│ │ ├── use-mobile.ts
│ │ └── useTheme.ts
│ ├── index.css
│ ├── lib
│ │ ├── axios.ts
│ │ ├── emailjs.ts
│ │ └── utils.ts
│ ├── main.tsx
│ ├── pages
│ │ ├── About.tsx
│ │ ├── Contact.tsx
│ │ ├── FAQ.tsx
│ │ ├── Features.tsx
│ │ ├── HomePage.tsx
│ │ ├── Login.tsx
│ │ ├── Register.tsx
│ │ ├── Testimonials.tsx
│ │ ├── TrackParcel.tsx
│ │ ├── Unauthorized.tsx
│ │ ├── Verify.tsx
│ │ ├── admin
│ │ │ ├── analytics
│ │ │ │ └── Analytics.tsx
│ │ │ ├── parcels
│ │ │ │ ├── ViewParcelDetails.tsx
│ │ │ │ └── ViewParcels.tsx
│ │ │ └── user
│ │ │ └── AllUsers.tsx
│ │ ├── receiver
│ │ │ ├── DeliveryHistory.tsx
│ │ │ └── IncomingParcels.tsx
│ │ └── sender
│ │ ├── MyParcels.tsx
│ │ └── ParcelStatus.tsx
│ ├── providers
│ │ └── theme-provider.tsx
│ ├── redux
│ │ ├── api
│ │ │ ├── axiosBaseQuery.ts
│ │ │ └── baseApi.ts
│ │ ├── features
│ │ │ ├── auth
│ │ │ │ └── authApi.ts
│ │ │ ├── coupon
│ │ │ │ └── couponApi.ts
│ │ │ ├── parcel
│ │ │ │ └── parcelApi.ts
│ │ │ └── user
│ │ │ └── userApi.ts
│ │ ├── hooks.ts
│ │ └── store.ts
│ ├── routes
│ │ ├── adminSidebarItems.ts
│ │ ├── constants.ts
│ │ ├── index.tsx
│ │ ├── receiverSidebarItems.ts
│ │ └── senderSidebarItems.ts
│ ├── types
│ │ ├── auth-type.ts
│ │ ├── index.ts
│ │ ├── parcel-type.ts
│ │ ├── sender-parcel-type.ts
│ │ └── user-type.ts
│ ├── utils
│ │ ├── generateRoutes.ts
│ │ ├── getNameInitials.ts
│ │ ├── getSidebarItems.ts
│ │ ├── getStatusColor.ts
│ │ └── withAuth.tsx
│ └── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
├── vercel.json
└── vite.config.ts👤 User Roles
| Role | Responsibilities |
|---|---|
SENDER | send/cancel/delete parcels, view own parcels, status |
RECEIVER | View incoming parcels, confirm delivery, delivery history |
DELIVERY_PERSONNEL | Currently admin can assign to parcel, and create |
ADMIN | Manage users, create admins and personnel, view analytics |
SUPER_ADMIN | Similar to admin |
Dashboard Screenshots
Admin Dashboard




Sender Dashboard


Receiver Dashboard


📦 Parcel Delivery Server
A modular and secure backend system for managing parcel deliveries. It features real-time tracking, role-based access control, and full parcel lifecycle management.
Live Demo: Parcel Delivery System.
Postman Collection: Parcel Delivery Server Postman Collection.
🧱 Features
- 🔐 Authentication: Email/password-based login using JWT.
- 🔁 Role-based access (
SENDER,RECEIVER,ADMIN,SUPER_ADMIN,DELIVERY_PERSONNEL) - 📦 Parcel lifecycle: Request, approve, picked, dispatch, deliver, block, cancel, flagged
- 🔄 Status Tracking: Track status changes for each parcel.
- 📲 OTP-based registration verification support
- 🧱 Scalable Modular Architecture
- 🎟️ Coupon support (only admin/super admin can create)
- ⚠️ Global error and validation handling
- 📧 Email notifications for OTP and password reset
🧩 Tech Stack
- Node.js + Express — Backend framework
- MongoDB + Mongoose — NoSQL Database with ODM
- Zod — Schema validation
- TypeScript — Optional typing (if enabled)
- JWT — Authentication
- dotenv — Config management
- Redis — Caching and session management
- EJS — Email templating
- Postman — API testing and documentation
- ESLint — Code quality and linting
- Prettier — Code formatting
- Nodemailer — Email sending
- Vercel — Deployment platform
🛠️ Getting Started
# 1. Clone the repo
git clone https://github.com/faisal-akbar/b5a5.git
cd b5a5
# 2. Install dependencies
npm install
# 3. Configure environment
cp .env.example .env
# 4. Update .env with your MongoDB URI, nodemailer credentials, redis credentials, etc.
PORT=5000
DB_URL=mongodb+srv://<db_user>:<db_password>@cluster0.4pnfxkm.mongodb.net/percel_delivery_system?retryWrites=true&w=majority&appName=Cluster0
NODE_ENV=development
# JWT
JWT_ACCESS_SECRET=access_secret
JWT_ACCESS_EXPIRES=3d
JWT_REFRESH_SECRET=refresh_secret
JWT_REFRESH_EXPIRES=10d
# BCRYPT
BCRYPT_SALT_ROUND=10
# SUPER ADMIN
SUPER_ADMIN_EMAIL=super@gmail.com
SUPER_ADMIN_PASSWORD=12345678
# Express Session
EXPRESS_SESSION_SECRET=express-session
# Frontend URL
FRONTEND_URL=http://localhost:5173
# SMTP GMAIL
SMTP_HOST=smtp.gmail.com
SMTP_PORT=465
SMTP_USER=fexample@gmail.com
SMTP_PASS=your_smtp_password_here
SMTP_FROM=fexample@gmail.com
# redis
REDIS_HOST=hostname_of_your_redis_server
REDIS_PORT=14282
REDIS_USERNAME=default
REDIS_PASSWORD=your_redis_password_here
# 5. Run locally
npm run dev👤 Dummy Users for Testing
I have added two function to create dummy users, one for super admin seedSuperAdmin() (enabled by default) and one for sender, receiver and admin. Uncomment this line seedDummyUsers() in src/server.ts if you want to seed dummy users.
Email and password for some dummy users:
// SUPER_ADMIN
email: "super@gmail.com",
password: "12345678"
// ADMIN
email: "admin@parcel.com",
password: "Ph@12345678"
// SENDER
email: "john.sender@parcel.com",
password: "sender123"
// RECEIVER
email: "bob.receiver@parcel.com",
password: "receiver123",📁 Folder Structure
── Parcel Delivery.postman_collection.json
├── README.md
├── eslint.config.mjs
├── package-lock.json
├── package.json
├── src
│ ├── app
│ │ ├── config
│ │ │ ├── env.ts
│ │ │ └── redis.config.ts
│ │ ├── interfaces
│ │ │ ├── error.types.ts
│ │ │ └── index.d.ts
│ │ ├── middlewares
│ │ │ ├── checkAuth.ts
│ │ │ ├── globalErrorHandler.ts
│ │ │ ├── notFound.ts
│ │ │ └── validateRequest.ts
│ │ ├── modules
│ │ │ ├── auth
│ │ │ │ ├── auth.controller.ts
│ │ │ │ ├── auth.routes.ts
│ │ │ │ └── auth.service.ts
│ │ │ ├── coupon
│ │ │ │ ├── coupon.controller.ts
│ │ │ │ ├── coupon.interface.ts
│ │ │ │ ├── coupon.model.ts
│ │ │ │ ├── coupon.routes.ts
│ │ │ │ ├── coupon.service.ts
│ │ │ │ ├── coupon.utils.ts
│ │ │ │ └── coupon.validation.ts
│ │ │ ├── otp
│ │ │ │ ├── otp.controller.ts
│ │ │ │ ├── otp.routes.ts
│ │ │ │ ├── otp.service.ts
│ │ │ │ └── otp.validation.ts
│ │ │ ├── parcel
│ │ │ │ ├── parcel.controller.ts
│ │ │ │ ├── parcel.interface.ts
│ │ │ │ ├── parcel.model.ts
│ │ │ │ ├── parcel.routes.ts
│ │ │ │ ├── parcel.service.ts
│ │ │ │ ├── parcel.utils.ts
│ │ │ │ └── parcel.validation.ts
│ │ │ └── user
│ │ │ ├── user.contants.ts
│ │ │ ├── user.controller.ts
│ │ │ ├── user.interface.ts
│ │ │ ├── user.model.ts
│ │ │ ├── user.routes.ts
│ │ │ ├── user.service.ts
│ │ │ └── user.validation.ts
│ │ ├── routes
│ │ │ └── index.ts
│ │ └── utils
│ │ ├── builder
│ │ │ ├── QueryBuilder.ts
│ │ │ └── constants.ts
│ │ ├── catchAsync.ts
│ │ ├── errorHelpers
│ │ │ ├── AppError.ts
│ │ │ ├── handleCastError.ts
│ │ │ ├── handleDuplicateError.ts
│ │ │ ├── handlerValidationError.ts
│ │ │ └── handlerZodError.ts
│ │ ├── generateTrackingId.ts
│ │ ├── jwt
│ │ │ ├── jwt.ts
│ │ │ ├── setCookie.ts
│ │ │ └── userTokens.ts
│ │ ├── seedDummyUser.ts
│ │ ├── seedSuperAdmin.ts
│ │ ├── sendEmail.ts
│ │ ├── sendResponse.ts
│ │ └── templates
│ │ ├── forgetPassword.ejs
│ │ └── otp.ejs
│ ├── app.ts
│ └── server.ts
├── tsconfig.json
└── vercel.json👤 User Roles
| Role | Responsibilities |
|---|---|
SENDER | send/cancel/delete parcels, view own parcels, status |
RECEIVER | View incoming parcels, confirm delivery, delivery history |
DELIVERY_PERSONNEL | Currently admin can assign to parcel, and create |
ADMIN | Manage users, create admins and personnel, manage coupons |
SUPER_ADMIN | Similar to admin but can create super admins |
📡 API Endpoints
🔐 Auth
| Method | Endpoint | Description |
|---|---|---|
| POST | /login | User login |
| POST | /refresh-token | Refresh JWT token |
| POST | /logout | Logout user |
| POST | /change-password | Change password |
| POST | /forgot-password | Forgot password request |
| POST | /reset-password | Reset password |
📲 OTP
| Method | Endpoint | Description |
|---|---|---|
| POST | /send | Send OTP to phone |
| POST | /verify | Verify OTP |
👤 Users
| Method | Endpoint | Role | Description |
|---|---|---|---|
| POST | /register | Public | Register sender/receiver |
| POST | /create-admin | ADMIN/SUPER_ADMIN | Create new admin |
| POST | /create-delivery-personnel | ADMIN/SUPER_ADMIN | Register delivery personnel |
| GET | /all-users | ADMIN/SUPER_ADMIN | Get all users |
| GET | /me | Authenticated | Get logged-in user |
| GET | /:id | Authenticated | Get user by ID |
| PATCH | /:id | Authenticated | Update user profile |
| PATCH | /:id/block-user | ADMIN/SUPER_ADMIN | Block/unblock user |
📦 Parcels
| Method | Endpoint | Role | Description |
|---|---|---|---|
| POST | / | SENDER | Create parcel |
| POST | /cancel/:id | SENDER | Cancel parcel |
| POST | /delete/:id | SENDER | Delete parcel |
| GET | /me | SENDER | View sender's parcels |
| GET | /:id/status-log | SENDER | View parcel status log |
| GET | /me/incoming | RECEIVER | Incoming parcels |
| GET | /me/history | RECEIVER | Delivery history |
| PATCH | /confirm/:id | RECEIVER | Confirm delivery |
| GET | /tracking/:trackingId | Public | Track parcel |
| GET | / | ADMIN | Get all parcels |
| POST | /create-parcel | ADMIN | Admin creates parcel |
| PATCH | /:id/delivery-status | ADMIN | Update delivery status |
| PATCH | /:id/block-status | ADMIN | Block/unblock a parcel |
| GET | /:id/details | ADMIN | Get parcel details |
📦 stats
| Method | Endpoint | Role | Description |
|---|---|---|---|
| GET | /parcels | ADMIN | Parcel statistics |
| GET | /user | ADMIN | User statistics |
🎟️ Coupons
| Method | Endpoint | Role | Description |
|---|---|---|---|
| POST | / | ADMIN | Create new coupon |
🔁 Parcel Lifecycle
🔄 Normal Flow
REQUESTED → APPROVED → PICKED → DISPATCHED → IN_TRANSIT → DELIVERED🛑 Exception Flows
Any Stage → FLAGGED → BLOCKED/CANCELLED
PICKED/DISPATCHED/IN_TRANSIT → RETURNED → REQUESTED
IN_TRANSIT → RESCHEDULED → IN_TRANSIT/DELIVERED/CANCELLED