Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
40c44d1
clean up code,add category chips, fix header UI
Mishra-coder Apr 3, 2026
87a2696
restore web UI with sidebar
Mishra-coder Apr 3, 2026
35e7842
scroll to top on product click
Mishra-coder Apr 3, 2026
f9dbb5f
fix:add mobile UI overlay to Preview
Mishra-coder Apr 3, 2026
a2c290f
feat: Add premium splash screens, fix expo development build, and cle…
Mishra-coder Apr 4, 2026
787e3e6
feat: Add PWA support, QR sharing, and brand splash fixes
Mishra-coder Apr 4, 2026
c5bb9e5
chore: Remove QR sharing section from preview
Mishra-coder Apr 4, 2026
3abf344
Final project-wide cleanup: removed comments, decommissioned /preview…
Mishra-coder Apr 4, 2026
9b0456a
Final cleanup: de-commissioned /preview, restored original UI, and fi…
Mishra-coder Apr 4, 2026
39ac8d6
refactor: Restore Nike data and clean up unused assets
Mishra-coder Apr 5, 2026
7a08c0e
feat: category filters,
Mishra-coder Apr 5, 2026
822083d
fix:splash screen,login UI update
Mishra-coder Apr 5, 2026
2ca4d84
fix: convert assets from JPEG to proper PNG format for Android build
Mishra-coder Apr 5, 2026
dff7301
fix: navigate to Home after login instead of goBack
Mishra-coder Apr 5, 2026
7117916
fix: auto navigate to Home
Mishra-coder Apr 5, 2026
4a56f84
fix: add placeholderTextColor to checkout address inputs
Mishra-coder Apr 5, 2026
85962a9
feat: enable OTA updates via expo-updates
Mishra-coder Apr 5, 2026
83a7ec5
fix: remove unused logo1.png, fix category string check
Mishra-coder Apr 5, 2026
3d42f59
feat: integrate Razorpay payment gateway for web and mobile
Mishra-coder Apr 5, 2026
e9ca0b4
fix: remove dotenv in production, update mobile API URL
Mishra-coder Apr 6, 2026
46df30e
docs: update README with Razorpay integration, payment testing, env vars
Mishra-coder Apr 6, 2026
8237d8a
Update README.md
Mishra-coder Apr 6, 2026
2ed85d0
feat: add unit tests, integration tests, ESLint, Dependabot config, i…
Mishra-coder Apr 6, 2026
9eb5c95
fix: load dotenv before all requires
Mishra-coder Apr 6, 2026
e6d398e
feat: add Cypress E2E tests for shop flow
Mishra-coder Apr 6, 2026
b9af3fc
fix: update Cypress tests for search and login flow
Mishra-coder Apr 6, 2026
4b8a610
chore: sync all changes
Mishra-coder Apr 6, 2026
573a233
fix: use node 20 and npm install in CI
Mishra-coder Apr 6, 2026
c7dc23d
fix: fix ESLint configs for backend and frontend
Mishra-coder Apr 6, 2026
d841053
fix: install @eslint/js and globals for backend lint
Mishra-coder Apr 6, 2026
6050161
Update README.md
Mishra-coder Apr 6, 2026
ab5a65c
fix: update app icon to logo.png
Mishra-coder Apr 6, 2026
8f96c72
ci: make EC2 deploy optional to avoid failure on session expiry
Mishra-coder Apr 6, 2026
b51d340
fix: update splash screen logo
Mishra-coder Apr 6, 2026
647719f
Update README.md
Mishra-coder Apr 6, 2026
2a16cd5
Update README.md
Mishra-coder Apr 6, 2026
d121b60
Bump vite from 8.0.3 to 8.0.8 in /frontend
dependabot[bot] Apr 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
version: 2
updates:
- package-ecosystem: npm
directory: /backend
schedule:
interval: weekly

- package-ecosystem: npm
directory: /frontend
schedule:
interval: weekly

- package-ecosystem: npm
directory: /mobile
schedule:
interval: weekly

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
71 changes: 59 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,76 @@ on:
branches: [main]

jobs:
build:
backend:
runs-on: ubuntu-latest

defaults:
run:
working-directory: backend

steps:
- name: Checkout code
uses: actions/checkout@v3
- uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
- uses: actions/setup-node@v3
with:
node-version: 18
cache: 'npm'
node-version: 20
cache: npm
cache-dependency-path: backend/package-lock.json

- name: Install dependencies
run: npm ci
run: npm install

- name: Lint
run: npm run lint

- name: Syntax Check
run: node --check server.js
- name: Run tests
run: npm test

- name: Build Docker image
run: docker build -t zappify-backend .
run: docker build -t zappify-backend .

frontend:
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend

steps:
- uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: 20
cache: npm
cache-dependency-path: frontend/package-lock.json

- name: Install dependencies
run: npm install

- name: Lint
run: npm run lint

deploy:
runs-on: ubuntu-latest
needs: backend
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
continue-on-error: true

steps:
- uses: actions/checkout@v3

- name: Deploy to EC2
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_KEY }}
script: |
if [ ! -d "/home/ubuntu/Zappify" ]; then
git clone https://github.com/Mishra-coder/Zappify.git /home/ubuntu/Zappify
fi
cd /home/ubuntu/Zappify
git pull origin main
cd backend
npm install --production
pm2 restart zappify-backend || pm2 start server.js --name zappify-backend
pm2 save
107 changes: 89 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,24 @@ Built with a modern MERN stack on the backend and React + React Native on the fr
## Live Demo

- **Website:** [zappify-sepia.vercel.app](https://zappify-sepia.vercel.app)
- **Phone Preview:** [zappify-sepia.vercel.app/preview](https://zappify-sepia.vercel.app/preview)
- **Download APK:** [Zappify Android App](https://expo.dev/accounts/devendra.mi/projects/zappify/builds/29e30585-c692-470b-b195-fd7af1822eb2)
- **Preview App:** [Preview App](https://drive.google.com/file/d/1IDo1ueM5tcDFiFk4r-4q5vFa-vUeZcyl/view)

---

## Technology Stack

### Web Frontend
![React](https://img.shields.io/badge/React_19-20232A?style=for-the-badge&logo=react&logoColor=61DAFB)
![Vite](https://img.shields.io/badge/Vite-646CFF?style=for-the-badge&logo=vite&logoColor=white)
![Framer Motion](https://img.shields.io/badge/Framer_Motion-0055FF?style=for-the-badge&logo=framer&logoColor=white)
![CSS3](https://img.shields.io/badge/CSS3-1572B6?style=for-the-badge&logo=css3&logoColor=white)
![Google OAuth](https://img.shields.io/badge/Google_OAuth-4285F4?style=for-the-badge&logo=google&logoColor=white)
![Lucide React](https://img.shields.io/badge/Lucide_React-F56565?style=for-the-badge&logo=lucide&logoColor=white)

### Mobile App
![React Native](https://img.shields.io/badge/React_Native-20232A?style=for-the-badge&logo=react&logoColor=61DAFB)
![Expo](https://img.shields.io/badge/Expo-000020?style=for-the-badge&logo=expo&logoColor=white)
![EAS Build](https://img.shields.io/badge/EAS_Build-4630EB?style=for-the-badge&logo=expo&logoColor=white)
![AsyncStorage](https://img.shields.io/badge/AsyncStorage-FF6B35?style=for-the-badge&logo=react&logoColor=white)
![React Navigation](https://img.shields.io/badge/React_Navigation-6B52AE?style=for-the-badge&logo=react&logoColor=white)

### Backend
![Node.js](https://img.shields.io/badge/Node.js-339933?style=for-the-badge&logo=nodedotjs&logoColor=white)
![Express.js](https://img.shields.io/badge/Express.js-000000?style=for-the-badge&logo=express&logoColor=white)
![MongoDB](https://img.shields.io/badge/MongoDB-47A248?style=for-the-badge&logo=mongodb&logoColor=white)
Expand All @@ -37,11 +33,14 @@ Built with a modern MERN stack on the backend and React + React Native on the fr
![Bcrypt](https://img.shields.io/badge/Bcrypt.js-003A70?style=for-the-badge&logo=letsencrypt&logoColor=white)
![Helmet](https://img.shields.io/badge/Helmet-FF6B35?style=for-the-badge&logo=helmet&logoColor=white)
![Morgan](https://img.shields.io/badge/Morgan-000000?style=for-the-badge&logo=npm&logoColor=white)

### Infrastructure
![Razorpay](https://img.shields.io/badge/Razorpay-02042B?style=for-the-badge&logo=razorpay&logoColor=3395FF)
![Vercel](https://img.shields.io/badge/Vercel-000000?style=for-the-badge&logo=vercel&logoColor=white)
![Docker](https://img.shields.io/badge/Docker-2496ED?style=for-the-badge&logo=docker&logoColor=white)
![GitHub Actions](https://img.shields.io/badge/GitHub_Actions-2088FF?style=for-the-badge&logo=githubactions&logoColor=white)
![AWS EC2](https://img.shields.io/badge/AWS_EC2-FF9900?style=for-the-badge&logo=amazonec2&logoColor=white)
![Jest](https://img.shields.io/badge/Jest-C21325?style=for-the-badge&logo=jest&logoColor=white)
![Cypress](https://img.shields.io/badge/Cypress-17202C?style=for-the-badge&logo=cypress&logoColor=white)
![ESLint](https://img.shields.io/badge/ESLint-4B32C3?style=for-the-badge&logo=eslint&logoColor=white)

---

Expand All @@ -50,12 +49,12 @@ Built with a modern MERN stack on the backend and React + React Native on the fr
```
+-------------------------------------------------------------------+
| |
| +-------------+ +-------------+ +-------------+ |
| | Front-end | | Back-end | | Database | |
| | ReactJS |<---->| NodeJS |<---->| MongoDB | |
| |UI Components| | ExpressJS | | Collections | |
| | API calls | |API endpoints| | Documents | |
| +-------------+ +-------------+ +-------------+ |
| +-------------+ +-------------+ +-------------+ |
| | Front-end | | Back-end | | Database | |
| | ReactJS |<---->| NodeJS |<---->| MongoDB | |
| |UI Components| | ExpressJS | | Collections | |
| | API calls | |API endpoints| | Documents | |
| +-------------+ +-------------+ +-------------+ |
| |
+-------------------------------------------------------------------+
```
Expand All @@ -75,16 +74,22 @@ Users {
String email UK
String password
Boolean isAdmin
Date createdAt
Date updatedAt
}

Products {
ObjectId _id PK
ObjectId user FK
String name
String image
String brand
String category
String description
Number price
Number countInStock
Date createdAt
Date updatedAt
}

Orders {
Expand All @@ -93,14 +98,32 @@ Orders {
Array orderItems
Object shippingAddress
String paymentMethod
Object paymentResult
Number taxPrice
Number shippingPrice
Number totalPrice
Boolean isPaid
Date paidAt
Boolean isDelivered
Date deliveredAt
Date createdAt
Date updatedAt
}
```

---

## Payment Testing

Razorpay is integrated in test mode. Use these credentials to test payments:

| Method | Details |
|---|---|
| Card | 5267 3181 8797 5449 / Expiry: 08/26 / CVV: 123 / OTP: 1234 |
| UPI | success@razorpay |

---

## What This Project Does

Zappify is built as a real-world e-commerce application that covers the complete shopping journey:
Expand All @@ -112,7 +135,6 @@ Zappify is built as a real-world e-commerce application that covers the complete
- Goes through a 3-step checkout (Bag → Address → Payment)
- Tracks their order with a live timeline
- Can cancel an order with a reason
- All of this works on both web and Android mobile app

---

Expand All @@ -127,13 +149,15 @@ Zappify is built as a real-world e-commerce application that covers the complete
- Add to cart with size validation
- Wishlist toggle on product cards and detail page
- 3-step checkout - Bag to Address to Payment (COD / UPI / Card)
- Razorpay payment gateway integration (UPI, Card, Netbanking, Wallet)
- Payment signature verification on backend
- Order history with tracking timeline
- Order cancellation with reason selection form
- Google OAuth 2.0 login
- Normal email/password sign up and sign in
- User-specific order history per account
- Persistent login via localStorage / AsyncStorage
- Full Android mobile app via Expo + EAS Build
- Persistent login via localStorage
- Progressive Web App (PWA) ready

### For Admins
- Secure JWT-protected API routes
Expand Down Expand Up @@ -168,6 +192,8 @@ PORT=5001
MONGO_URI=your_mongodb_uri
JWT_SECRET=your_secret_key
NODE_ENV=development
RAZORPAY_KEY_ID=your_razorpay_key_id
RAZORPAY_KEY_SECRET=your_razorpay_key_secret
```

```bash
Expand Down Expand Up @@ -203,7 +229,6 @@ Zappify/
│ ├── components/
│ ├── data/products.js
│ ├── App.jsx
│ ├── Preview.jsx
│ ├── main.jsx
│ └── index.css
├── mobile/
Expand Down Expand Up @@ -234,6 +259,52 @@ Zappify/
| GET | /api/products | Get all products | No |
| GET | /api/products/:id | Get product by ID | No |
| POST | /api/products | Create product | Admin |
| POST | /api/payment/create-order | Create Razorpay order | No |
| POST | /api/payment/verify | Verify payment signature | No |

---

## Frontend Environment Variables

Create `frontend/.env`:
```env
VITE_API_URL=http://localhost:5001
VITE_RAZORPAY_KEY_ID=your_razorpay_key_id
```

---

## CI/CD & Testing

- GitHub Actions pipeline runs on every push and pull request
- Linting with ESLint on both frontend and backend
- Unit tests with Jest for email validation logic
- Integration tests with Jest + Supertest for API routes
- E2E tests with Cypress simulating real user flows (homepage, search, cart, login)
- Automated deployment to AWS EC2 via SSH on every push to main
- Dependabot configured for weekly dependency updates

Run backend tests:
```bash
cd backend
npm test
```

Run E2E tests:
```bash
cd frontend
npm run cy:open
```

---

## AWS EC2 Deployment

Backend is also deployed on AWS EC2 with PM2 process manager.

- EC2 instance: `13.218.101.177:5001`
- PM2 keeps the server alive and auto-restarts on crash
- GitHub Actions auto-deploys on every push to main

---

Expand Down
2 changes: 2 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ PORT=5001
MONGO_URI=your_mongodb_atlas_uri_here
JWT_SECRET=your_super_secret_key_here
NODE_ENV=development
RAZORPAY_KEY_ID=rzp_test_xxxxxxxxxxxxxx
RAZORPAY_KEY_SECRET=your_key_secret_here
7 changes: 2 additions & 5 deletions backend/config/db.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
const mongoose = require('mongoose');
const dotenv = require('dotenv');

dotenv.config();

const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI);
console.log(`Connection established with MongoDB: ${conn.connection.host}`);
console.log(`Connected to MongoDB: ${conn.connection.host}`);
} catch (error) {
console.error(`Something went wrong: ${error.message}`);
console.error(`DB Error: ${error.message}`);
process.exit(1);
}
};
Expand Down
3 changes: 2 additions & 1 deletion backend/controllers/userController.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const { validateEmail } = require('../utils/validate');

const generateToken = (id) => {
return jwt.sign({ id }, process.env.JWT_SECRET, {
Expand Down Expand Up @@ -28,7 +29,7 @@ const authUser = async (req, res) => {
const registerUser = async (req, res) => {
const { name, email, password } = req.body;

if (!email.includes('@') || !email.includes('.')) {
if (!validateEmail(email)) {
return res.status(400).json({ message: 'Please enter a valid email' });
}

Expand Down
28 changes: 28 additions & 0 deletions backend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const js = require('@eslint/js');
const globals = require('globals');

module.exports = [
js.configs.recommended,
{
files: ['**/*.js'],
ignores: ['node_modules/**'],
languageOptions: {
globals: {
...globals.node,
},
},
rules: {
'no-unused-vars': 'warn',
'no-console': 'off',
},
},
{
files: ['tests/**/*.js'],
languageOptions: {
globals: {
...globals.node,
...globals.jest,
},
},
},
];
Loading
Loading