A production-oriented workforce and meter management web application built with Next.js and React.
Assign Meter Web provides the frontend interface for managing meters, field operations, assignments, users, locations, reports, and other operational workflows through a centralized web application.
The application communicates with a dedicated backend API and uses cookie-based authentication to protect application routes and user sessions.
- Overview
- Key Features
- Technology Stack
- Application Architecture
- Project Structure
- Authentication
- Route Protection
- Backend Integration
- Real-Time Communication
- File and Spreadsheet Handling
- Maps and Location Features
- UI and Styling
- Environment Variables
- Getting Started
- Development
- Production Build
- Deployment
- Code Organization Guidelines
- Security Considerations
- Troubleshooting
- Future Improvements
- Related Repository
- License
Assign Meter Web is the frontend application for the Assign Meter platform.
The application is designed around operational workflows where authenticated users can interact with meter-related data and perform actions based on their permissions.
The frontend is responsible for:
- User interface and user experience
- Authentication-aware routing
- Meter management interfaces
- Assignment workflows
- Data visualization
- Reports and operational views
- Spreadsheet processing
- Map-based interfaces
- Real-time UI updates
- Browser-side notifications and application interactions
- Communication with the Assign Meter backend
The frontend is built using the Next.js App Router architecture.
The application uses an authentication cookie named:
access_token
The cookie is checked by Next.js middleware before allowing access to protected application routes.
Authentication-related responsibilities include:
- Login flow
- Authentication-aware routing
- Redirecting unauthenticated users to
/login - Redirecting authenticated users away from
/login - Maintaining authentication through browser cookies
- Communicating with the backend authentication system
The frontend should not be considered the final security boundary. Authorization must always be enforced by the backend.
The application provides interfaces for working with meter-related operational data.
Typical workflows include:
- Viewing meter records
- Searching and filtering meters
- Managing meter information
- Assigning meters
- Tracking assignment-related information
- Viewing meter status
- Working with operational meter data
The application supports workflows around assigning operational resources to field users.
Depending on user permissions, the application can be used to:
- View assignments
- Create assignments
- Update assignments
- Track assignment status
- Review assigned work
- Manage assignment-related information
The frontend provides interfaces for managing users and workforce-related operations.
The application is designed to support role-based workflows where different users can have different capabilities.
The frontend should use permissions to improve the user experience, while the backend remains responsible for enforcing authorization.
The application includes interfaces for viewing operational information and reports.
Reports can be used to:
- Review operational activity
- Inspect meter-related information
- Filter data
- Analyze records
- Export or process data where supported
The project includes the xlsx package for working with Excel/spreadsheet data.
This allows the frontend to support workflows involving:
- Excel files
- Spreadsheet parsing
- Spreadsheet data processing
- Import/export workflows
- Bulk operational data handling
Large file uploads should be handled carefully and should not unnecessarily pass through the Next.js server when a direct object-storage upload architecture is available.
The project includes map-related libraries:
- Leaflet
- React Leaflet
- Google Maps React integration
These libraries provide the foundation for location-based interfaces and map visualization.
Possible use cases include:
- Showing meter locations
- Displaying field locations
- Visualizing geographic data
- Selecting locations
- Mapping operational activities
The Assign Meter platform supports real-time communication between the backend and frontend.
The frontend can consume real-time events to update the interface without requiring the user to manually refresh the page.
Typical real-time workflows include:
Backend event
↓
Real-time connection
↓
Frontend receives event
↓
Application state updates
↓
UI updates
For long-running real-time connections, the frontend should correctly handle:
- Connection establishment
- Connection cleanup
- Reconnection
- Component unmounting
- Duplicate connections
- Error handling
| Technology | Purpose |
|---|---|
| Next.js | React framework and application runtime |
| React | UI development |
| JavaScript | Application programming language |
| React DOM | Browser rendering |
Current project versions are defined in package.json.
| Technology | Purpose |
|---|---|
| Tailwind CSS | Utility-first styling |
| Sass | CSS preprocessing |
| shadcn | UI component tooling |
| Radix UI | Accessible UI primitives |
| Lucide React | Icons |
| Phosphor Icons | Icons |
| class-variance-authority | Component variants |
| clsx | Conditional class names |
| tailwind-merge | Tailwind class merging |
| tw-animate-css | Tailwind animations |
| Technology | Purpose |
|---|---|
| Leaflet | Interactive maps |
| React Leaflet | React integration for Leaflet |
| Google Maps API | Google Maps integration |
| Technology | Purpose |
|---|---|
| XLSX | Excel/spreadsheet processing |
| Technology | Purpose |
|---|---|
| ESLint | Code quality and linting |
| PostCSS | CSS processing |
| Autoprefixer | CSS vendor compatibility |
The frontend follows a Next.js application architecture.
At a high level:
┌─────────────────────┐
│ Browser │
└──────────┬──────────┘
│
│
┌──────────▼──────────┐
│ Next.js App │
│ │
│ App Router │
│ Components │
│ Contexts │
│ UI │
│ Middleware │
└──────────┬──────────┘
│
┌────────────────┴────────────────┐
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Backend API │ │ Real-Time Layer │
│ │ │ │
│ Node.js │ │ SSE / Events │
│ Express │ │ │
└────────┬────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ MongoDB │
└─────────────────┘
│
▼
┌─────────────────┐
│ AWS S3 │
│ File Storage │
└─────────────────┘
The frontend should primarily be responsible for presentation, user interaction, client-side state, and communicating with backend services.
Business-critical authorization and data validation must remain on the backend.
Current repository structure includes the following major directories:
Assign-Meter-Web/
│
├── app/
│ ├── ...
│ └── ...
│
├── components/
│ ├── ...
│ └── ...
│
├── contexts/
│ ├── ...
│ └── ...
│
├── lib/
│ ├── ...
│ └── ...
│
├── public/
│ ├── ...
│ └── ...
│
├── middleware.js
├── next.config.mjs
├── eslint.config.mjs
├── jsconfig.json
├── postcss.config.mjs
├── components.json
├── package.json
├── package-lock.json
└── README.md
The repository currently separates:
Contains the Next.js application routes and pages.
This is the primary application layer using the Next.js App Router.
Contains reusable React components.
Components should generally contain UI and interaction logic that can be reused across multiple pages.
Contains React Context providers and shared client-side state.
Contexts should be used for state that genuinely needs to be shared across multiple parts of the application.
Contains reusable application utilities and supporting logic.
This is a suitable place for:
- API helpers
- Utility functions
- Client-side services
- Shared configuration
- Data transformation helpers
Contains static assets that can be served directly by Next.js.
Handles authentication-aware route protection before requests reach application pages.
Authentication is based on an access_token cookie.
The current middleware reads the cookie:
const access_token = request.cookies.get("access_token")?.value;If the user does not have an access token and attempts to access a protected route, the middleware redirects the user to:
/login
If an authenticated user attempts to access /login, the middleware redirects them to:
/meter
The current middleware applies to application routes while excluding Next.js internal assets, API routes, and the favicon.
The current authentication flow is:
User opens application
↓
Next.js Middleware
↓
Read access_token cookie
↓
┌───────────────┐
│ Token exists? │
└───────┬───────┘
│
┌────┴────┐
│ │
YES NO
│ │
▼ ▼
Allow /login
route redirect
For /login:
Authenticated user
↓
/login
↓
/meter
The middleware only provides route-level protection for the frontend.
It must not be treated as the actual authorization mechanism.
The backend must independently:
- Verify the authentication token.
- Verify that the user exists.
- Verify the user's permissions.
- Verify access to the requested resource.
- Validate all incoming data.
The frontend communicates with the Assign Meter backend API.
The backend repository is responsible for:
- Authentication
- Authorization
- Database operations
- Business logic
- File storage
- Meter management
- Workforce operations
- Notifications
- Real-time events
- Server-side validation
The frontend should not duplicate backend business rules unnecessarily.
API communication should ideally be centralized rather than directly calling fetch() from many unrelated components.
Recommended structure:
lib/
└── api/
├── auth.js
├── meters.js
├── users.js
├── assignments.js
├── reports.js
└── notifications.js
A centralized API layer makes it easier to manage:
- Base URLs
- Authentication
- Headers
- Credentials
- Error handling
- Response parsing
- API changes
The application can receive real-time updates from the backend.
The conceptual flow is:
Backend
│
│ event
▼
Real-Time Connection
│
▼
Frontend
│
▼
State Update
│
▼
UI Update
Real-time communication is useful for operational interfaces where users should see changes without manually refreshing the page.
Examples include:
- New meter records
- Assignment changes
- Operational status updates
- Notifications
- Other application events
The frontend includes the xlsx library for spreadsheet processing.
Typical workflow:
User selects Excel file
↓
Browser reads file
↓
Spreadsheet parsed
↓
Data validated
↓
Data sent to backend
For large files, avoid unnecessarily routing the entire file through the Next.js application server.
A preferred architecture for large uploads is:
Browser
│
│ request upload permission
▼
Backend
│
│ generate signed upload URL
▼
Browser
│
│ direct upload
▼
AWS S3
This reduces the amount of large-file traffic handled by the Next.js server.
The project includes both Leaflet and Google Maps integrations.
Installed packages include:
leaflet
react-leaflet
@react-google-maps/api
These should be used according to the specific requirement of each map-based feature.
When implementing map-heavy components:
- Avoid unnecessary map re-renders.
- Load maps only where required.
- Clean up event listeners.
- Avoid storing large geographic datasets unnecessarily in React state.
- Consider server-side filtering for large datasets.
- Keep API keys restricted where applicable.
The project uses a combination of:
- Tailwind CSS
- Sass
- shadcn tooling
- Radix UI
- Lucide React
- Phosphor Icons
The repository also contains components.json, indicating the use of shadcn-related component tooling.
Reusable UI should generally be placed in:
components/
rather than duplicated across pages.
Create a local environment file:
.env.local
Environment variables required by the frontend should be documented here.
For example:
NEXT_PUBLIC_BACKEND_URL=http://localhost:5000For production:
NEXT_PUBLIC_BACKEND_URL=https://your-backend-domain.comOnly variables that are intentionally exposed to the browser should use the NEXT_PUBLIC_ prefix.
Never place secrets such as:
JWT_SECRET
AWS_SECRET_ACCESS_KEY
DATABASE_PASSWORD
PRIVATE_KEYS
inside NEXT_PUBLIC_* variables.
Anything prefixed with NEXT_PUBLIC_ can become available to browser-side code.
Before running the project, install:
- Node.js
- npm
Recommended:
node --version
npm --versionThe project uses Next.js 16 and React 19 as defined in the current package.json.
Clone the repository:
git clone https://github.com/Codewithajoydas/Assign-Meter-Web.gitMove into the project:
cd Assign-Meter-WebInstall dependencies:
npm installCreate:
.env.local
Add the required frontend environment variables.
Example:
NEXT_PUBLIC_BACKEND_URL=http://localhost:5000Make sure the backend server is also running and accessible from the configured URL.
Start the development server:
npm run devThe application will normally be available at:
http://localhost:3000
The development command is defined in package.json as:
"dev": "next dev"Run ESLint:
npm run lintThe project currently uses ESLint 9 and the Next.js ESLint configuration.
Before committing significant changes:
npm run lintCreate a production build:
npm run buildThen start the production server:
npm run startThe available scripts are currently:
{
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
}The frontend is deployed using Vercel.
Production URL:
https://assign-meter-web.vercel.app
The GitHub repository currently identifies this deployment URL as its project website.
Before deploying:
[ ] npm run lint
[ ] npm run build
[ ] Environment variables configured
[ ] Backend URL points to production backend
[ ] Authentication cookies configured correctly
[ ] CORS configured on backend
[ ] Production API accessible
[ ] Large file uploads tested
[ ] Real-time connections tested
[ ] Browser notifications tested where applicable
A recommended development workflow is:
1. Create feature branch
↓
2. Implement feature
↓
3. Run lint
↓
4. Run production build
↓
5. Test authentication
↓
6. Test API integration
↓
7. Test relevant workflows
↓
8. Commit changes
↓
9. Push branch
↓
10. Review
↓
11. Merge
Avoid creating extremely large components containing:
- API requests
- Business logic
- UI
- Validation
- State management
- Data transformation
all in one file.
Prefer:
Page
├── Component
├── Component
├── Hook
└── API service
Avoid:
// Large component
fetch(...)
fetch(...)
fetch(...)
fetch(...)Prefer:
Component
↓
API service
↓
Backend
A component should primarily manage:
- Rendering
- User interaction
- UI state
Complex business logic should be moved to reusable utilities, hooks, services, or the backend where appropriate.
Do not trust the frontend to determine whether a user is authorized.
The backend must validate every protected request.
Frontend permission checks are useful for UI control:
Hide button
Disable action
Hide navigation item
But they are not security mechanisms.
The backend must enforce:
User
↓
Role
↓
Permission
↓
Resource
↓
Action
Never expose:
- Database credentials
- JWT signing secrets
- AWS secret keys
- Private cryptographic keys
- Internal service credentials
to browser-side JavaScript.
Authentication cookies should be configured securely by the authentication server.
Production authentication should consider:
HttpOnly
Secure
SameSite
Expiration
When working on the application:
Use server components where client-side functionality is not required.
Be careful with:
- Context providers
- Large arrays in state
- Map components
- Real-time event handlers
- Large tables
Do not load thousands of records into the browser when server-side pagination can be used.
Large files should preferably use direct object-storage upload flows instead of passing through the frontend server.
Check:
1. Backend is running
2. NEXT_PUBLIC_BACKEND_URL is correct
3. CORS configuration is correct
4. Authentication cookie exists
5. Backend route exists
6. Browser Network tab
Check:
access_token cookie
↓
Cookie domain
↓
Cookie SameSite
↓
Cookie Secure setting
↓
Backend authentication
The middleware currently redirects requests without the access_token cookie to /login.
Check:
NEXT_PUBLIC_BACKEND_URL
CORS allowed origin
Cookie configuration
HTTPS
Backend availability
Check:
API key
Google Maps configuration
Leaflet CSS
Browser console
Network requests
Check:
Backend event stream
Connection status
Browser Network tab
EventSource lifecycle
Component cleanup
Reconnection logic
The following improvements are recommended as the application continues to grow.
- Centralized API client
- Dedicated API service modules
- Consistent API error handling
- Shared validation utilities
- Better client-side state boundaries
- Explicit public/private route configuration
- Better expired-session handling
- Refresh-token strategy if required
- Centralized authentication state
- Presigned S3 uploads
- Client-side upload progress
- Large-file handling
- File type validation
- Upload cancellation
- Retry handling
- Automatic reconnection
- Connection status indicator
- Event deduplication
- Centralized event subscription management
Introduce automated testing for:
- Authentication flows
- Protected routes
- Critical forms
- API services
- Assignment workflows
- Spreadsheet processing
- Permission-based UI
Add GitHub Actions for:
Pull Request
↓
Install
↓
Lint
↓
Build
↓
Tests
↓
Merge
Before considering the frontend production-ready:
- All critical workflows tested
- No unnecessary console logs
- No debug code
- No dead imports
- No unused components
- No hard-coded production URLs
- Secure cookies
- Correct expiration
- Expired session handling
- Backend authorization verified
- Centralized API communication
- Consistent error handling
- Loading states
- Empty states
- Network failure handling
- File type validation
- File size validation
- Large upload architecture reviewed
- Upload failure handling
- Production build tested
- Large tables optimized
- Maps optimized
- Real-time connections cleaned up
- Unnecessary client components removed
- Production environment variables configured
- Backend CORS configured
- HTTPS enabled
- Production build successful
- Authentication tested in production
Assign Meter Web depends on the Assign Meter backend application.
Backend repository:
https://github.com/Codewithajoydas/Assign-Meter-Backend
The backend provides the API, authentication, authorization, database operations, file storage, and server-side business logic used by this frontend.
Frontend:
https://github.com/Codewithajoydas/Assign-Meter-Web
Production:
https://assign-meter-web.vercel.app
Ajoy Das
GitHub:
https://github.com/Codewithajoydas
This project is currently maintained as a private application codebase.
If this repository is intended for public distribution, add an explicit license and update this section accordingly.
Assign Meter Web is an actively developed application.
The codebase is evolving as new operational workflows, authentication features, real-time functionality, reporting capabilities, and file-processing requirements are added.
For production changes, prioritize:
- Security
- Data integrity
- Authentication and authorization
- Reliability
- Performance
- Maintainability
- User experience