Stockly is a ReactJS-based inventory management application built with Next.js. It is designed to help businesses efficiently manage their product inventory. The application includes features such as product listing, adding new products, editing existing products, filtering products, and more. It also incorporates robust security measures like JWT-based authentication, password hashing, and middleware for secure API interactions.
Online-Live: https://stockly-inventory.vercel.app/
- Product Listing: View a list of all products with details such as name, SKU, status, quantity in stock, price, and supplier.
- Add Product: Add new products to the inventory with details such as name, SKU, status, quantity, price, and supplier.
- Edit Product: Edit existing product details.
- Delete Product: Remove products from the inventory.
- Filter Products: Filter products based on status, category, and supplier.
- Search Products: Search for products by name or SKU.
- Sort Products: Sort products by attributes like name, price, or quantity.
- User Login and Registration: Secure user authentication using JWT (JSON Web Tokens).
- Password Hashing: Passwords are hashed using bcrypt for secure storage.
- Session Management: Tokens are stored securely in cookies for session management.
- The application is fully responsive and works seamlessly on devices of all screen sizes, including desktops, tablets, and mobile phones.
- RESTful APIs: The backend is built with Next.js API routes, providing endpoints for managing products, users, and authentication.
- Middleware: Middleware is used to validate tokens and protect sensitive routes.
- MongoDB: The application uses MongoDB as the database to store product and user information.
- Prisma ORM: Prisma is used as the ORM for database schema management and queries.
- Registration: Users register by providing their email and password. The password is hashed using bcrypt before being stored in the database.
- Login: Users log in with their email and password. A JWT is generated upon successful login and stored in a secure cookie.
- Token Validation: Middleware validates the JWT for protected routes to ensure only authenticated users can access them.
- Add Product: Users can add products by filling out a form with details like name, SKU, category, supplier, price, and quantity.
- Edit Product: Users can edit product details through a dialog form.
- Delete Product: Users can delete products, which removes them from the database.
- Category Filter: Products can be filtered by category using a dropdown menu.
- Status Filter: Products can be filtered by their stock status (e.g., Available, Stock Low, Stock Out).
- Supplier Filter: Products can be filtered by supplier.
- Search: Users can search for products by name or SKU.
The database schema is managed using Prisma and stored in MongoDB. Below is an example of the schema:
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "rhel-openssl-3.0.x"]
}
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String
email String @unique
password String
createdAt DateTime @default(now())
products Product[]
categories Category[]
suppliers Supplier[]
sessions Session[]
}
model Product {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String
sku String @unique
price Float
quantity Int
status String
createdAt DateTime @default(now())
userId String @db.ObjectId
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
categoryId String @db.ObjectId
category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade)
supplierId String @db.ObjectId
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
}
model Category {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String
userId String @db.ObjectId
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
products Product[]
}
model Supplier {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String
userId String @db.ObjectId
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
products Product[]
}
model Session {
id String @id @default(auto()) @map("_id") @db.ObjectId
userId String @db.ObjectId
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
expires DateTime
sessionToken String @unique
}
model VerificationToken {
id String @id @default(auto()) @map("_id") @db.ObjectId
identifier String
token String @unique
expires DateTime
}
- Passwords are hashed using bcrypt before being stored in the database. This ensures that even if the database is compromised, passwords remain secure.
- Token Generation: Upon login, a JWT is generated and sent to the client.
- Token Storage: The token is stored in a secure, HTTP-only cookie to prevent XSS attacks.
- Token Validation: Middleware validates the token for protected routes.
- Middleware is used to protect sensitive API routes by validating the JWT and ensuring the user is authenticated.
git clone https://github.com/your-username/stockly.git
cd stockly
npm install
If you get error installing any npm dependency, it might be due to using Next.js 15 and the latest version of React and tanstack/table together. Tp avoid that, run:
npm install --force
Create a .env
file in the root directory and add the following environment variables:
DATABASE_URL=mongodb+srv://<username>:<password>@cluster.mongodb.net/stockly
JWT_SECRET=your_jwt_secret
npm run dev
Open your browser and navigate to http://localhost:3000
- POST /api/auth/register: Register a new user.
- POST /api/auth/login: Log in a user and return a JWT.
- GET /api/auth/me: Get the authenticated user's details.
- GET /api/products: Get a list of all products.
- POST /api/products: Add a new product.
- PUT /api/products/:id: Update an existing product.
- DELETE /api/products/:id: Delete a product.
- GET /api/categories: Get a list of all categories.
- POST /api/categories: Add a new categories.
- PUT /api/categories/:id: Update an existing categories.
- DELETE /api/categories/:id: Delete a categories.
- GET /api/suppliers: Get a list of all suppliers.
- POST /api/suppliers: Add a new suppliers.
- PUT /api/suppliers/:id: Update an existing suppliers.
- DELETE /api/suppliers/:id: Delete a suppliers.
stockly
├── app
│ ├── AppHeader
│ │ └── AppHeader.tsx
│ ├── AppTable
│ │ ├── AppTable.tsx
│ │ ├── ProductDialog
│ │ │ ├── ProductDialog.tsx
│ │ │ ├── _components
│ │ │ │ ├── ProductName.tsx
│ │ │ │ ├── Price.tsx
│ │ │ │ ├── ProductCategory.tsx
│ │ │ │ ├── Quantity.tsx
│ │ │ │ ├── SKU.tsx
│ │ │ │ ├── Status.tsx
│ │ │ │ └── Supplier.tsx
│ │ ├── dropdowns
│ │ │ ├── StatusDropDown.tsx
│ │ │ └── CategoryDropDown.tsx
│ ├── DeleteDialog
│ │ └── DeleteDialog.tsx
│ ├── Products
│ │ ├── ProductTable.tsx
│ │ └── columns.tsx
│ ├── authContext.tsx
│ ├── login
│ │ └── page.tsx
│ ├── register
│ │ └── page.tsx
│ ├── page.tsx
├── components
│ └── ui
│ ├── badge.tsx
│ ├── button.tsx
│ ├── card.tsx
│ ├── dropdown-menu.tsx
│ ├── input.tsx
│ ├── label.tsx
│ ├── popover.tsx
│ ├── select.tsx
│ ├── separator.tsx
│ ├── table.tsx
│ └── textarea.tsx
├── public
├── styles
│ └── globals.css
├── .gitignore
├── package.json
├── README.md
└── tsconfig.json