Skip to content

Vansh1811/unfold-website

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

40 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation


✨ Features

Frontend

  • Multi-page SPA with React Router β€” Home, About, Services, Blog, Contact, Legal
  • Services Hierarchy β€” 3-level nested routing (overview β†’ category β†’ detail)
  • Blog System β€” Static blog listing with individual post pages
  • Contact Form β€” Validated with React Hook Form + Zod, submits to backend API
  • Animations β€” Framer Motion page transitions and component animations
  • Fully Responsive β€” Mobile-first design with Tailwind CSS
  • Dark/Light Mode Ready β€” next-themes integration
  • Accessible Components β€” Built on Radix UI primitives via shadcn/ui
  • Scroll Restoration β€” Automatically scrolls to top on every route change
  • Toast Notifications β€” Sonner for success/error feedback on form submit
  • Legal Pages β€” Privacy Policy, Terms of Service, Cookie Policy

Backend

  • Contact Form Email Delivery β€” Sends formatted HTML email to admin on form submission
  • Zoho SMTP Integration β€” Secure email via port 465 with TLS
  • Rate Limiting β€” 100 req/15 min general limiter; strict 3 req/hour on /contact
  • Security Hardening β€” Helmet CSP, X-Frame-Options, X-XSS-Protection headers
  • Structured Logging β€” Winston logger with file rotation + Morgan HTTP logs
  • Graceful Shutdown β€” SIGTERM/SIGINT handlers with 10-second force-exit fallback
  • Health Check Endpoint β€” Returns uptime, memory usage, environment info
  • API Documentation Endpoint β€” Self-documenting /api/v1/docs route
  • Error Handling β€” Global error middleware + unhandledRejection/uncaughtException handlers
  • Response Compression β€” gzip compression via compression middleware
  • CORS β€” Whitelisted origins for local dev and production domains

πŸ“‘ API Reference

Base URL: https://your-render-url.onrender.com

General

Method Endpoint Description
GET /api/v1 Welcome message + status
GET /api/v1/health Server health, uptime, memory
GET /api/v1/docs API documentation

Contact

Method Endpoint Auth Rate Limit Description
POST /api/v1/contact/submit None 3 req/hour Submit contact form
GET /api/v1/contact/health None General Contact service status

POST /api/v1/contact/submit

Request Body:

{
  "name": "John Doe",           // required
  "email": "john@example.com",  // required
  "phone": "+91 9876543210",    // required
  "message": "Hello...",        // required
  "company": "Acme Corp",       // optional
  "service": "Compliance",      // optional
  "serviceSubcategory": "FEMA"  // optional
}

Success Response (200):

{
  "success": true,
  "message": "Email sent successfully"
}

Error Response (400 β€” Missing Fields):

{
  "success": false,
  "error": {
    "message": "Missing required fields",
    "code": 400
  }
}

Error Response (429 β€” Rate Limited):

{
  "success": false,
  "error": {
    "message": "Too many contact form submissions, try again later.",
    "code": 429
  }
}

πŸ” Environment Variables

Backend (server/.env)

# Server
NODE_ENV=development
PORT=5000

# Database (optional β€” not required for current features)
MONGODB_URI=mongodb+srv://<user>:<pass>@cluster.mongodb.net/unfold

# JWT (configured for future admin panel)
JWT_SECRET=your_super_secret_jwt_key
JWT_EXPIRES_IN=7d

# Zoho SMTP Email
SMTP_HOST=smtp.zoho.in
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=aryan@unfoldfinlegsolutions.com
SMTP_PASS=your_zoho_app_password
SMTP_FROM="Unfold Finleg Solutions" <aryan@unfoldfinlegsolutions.com>
ADMIN_EMAIL=aryan@unfoldfinlegsolutions.com

# CORS (comma-separated for multiple origins on Render)
CORS_ORIGIN=https://unfoldfinlegsolutions.com,https://your-vercel-url.vercel.app

# Rate Limiting
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX=100

# Logging
LOG_LEVEL=info
LOG_DIR=./logs

⚠️ Important: In production, JWT_SECRET, MONGODB_URI, SMTP_USER, SMTP_PASS, and ADMIN_EMAIL are required β€” the server will exit with code 1 if any are missing.

Frontend (user/.env)

# Backend API URL
VITE_API_BASE_URL=https://your-render-backend.onrender.com

πŸš€ Getting Started

Prerequisites

  • Node.js v18+ (recommended: v20 LTS)
  • npm v9+
  • A Zoho Mail account (or any SMTP provider)

Frontend Setup

# 1. Navigate to frontend directory
cd user

# 2. Install dependencies
npm install

# 3. Create environment file
cp .env.example .env
# Set VITE_API_BASE_URL to your backend URL

# 4. Start development server
npm run dev
# Runs on http://localhost:5173

Backend Setup

# 1. Navigate to backend directory
cd server

# 2. Install dependencies
npm install

# 3. Create environment file
cp .env.example .env
# Fill in all required variables (see Environment Variables section)

# 4. Start development server (with hot reload)
npm run dev
# Runs on http://localhost:5000

# 5. Verify it's running
curl http://localhost:5000/api/v1/health

πŸ“œ Scripts

Frontend (/user)

npm run dev        # Start Vite dev server with HMR
npm run build      # TypeScript compile + Vite production build
npm run preview    # Preview production build locally
npm run clean      # Remove node_modules/.vite and dist

Backend (/server)

npm run dev        # ts-node-dev with hot reload (--respawn --transpile-only)
npm run build      # Compile TypeScript β†’ dist/
npm run start      # Run compiled JS (node dist/index.js) β€” used in production
npm run lint       # ESLint check on .ts files

πŸ—Ί Pages & Routing

Route Component Description
/ Home.tsx Hero, services overview, call-to-action
/about About.tsx Company info, team, mission
/services Services/1_Services.tsx All service categories
/services/:categorySlug Services/2_ServiceCategory.tsx Category-level services
/services/:categorySlug/:serviceSlug Services/3_ServiceDetail.tsx Individual service detail
/blog Blogs/1_BlogList.tsx All blog posts
/blog/:slug Blogs/2_BlogDetail.tsx Single blog post
/contact Contact.tsx Contact form + company details
/privacy Legal/x_PrivacyPolicy.tsx Privacy Policy
/terms Legal/x_TermsOfService.tsx Terms of Service
/cookies Legal/x_CookiePolicy.tsx Cookie Policy
* NotFound.tsx 404 fallback

All routes are wrapped in a persistent <Navbar /> and <Footer /> layout. <ScrollToTop /> ensures the page scrolls to the top on every route transition.


βš™οΈ Backend Architecture

Middleware Stack (in order)

Request β”‚ β”œβ”€β”€ helmet() β†’ Security headers (CSP, X-Frame-Options, etc.) β”œβ”€β”€ compression() β†’ gzip response compression β”œβ”€β”€ morgan() β†’ HTTP access logging (combined/dev) β”œβ”€β”€ cors() β†’ Whitelist: localhost + unfoldfinlegsolutions.com β”œβ”€β”€ generalLimiter β†’ 100 req / 15 min per IP on /api/* β”œβ”€β”€ contactLimiter β†’ 3 req / 15 min per IP on /api/v1/contact β”œβ”€β”€ express.json() β†’ JSON body parsing (max 10mb) β”œβ”€β”€ express.urlencoded() β†’ URL-encoded body parsing (max 10mb) β”œβ”€β”€ Custom Headers β†’ nosniff, DENY framing, XSS protection β”‚ └── Routes β”œβ”€β”€ GET /api/v1 β†’ Welcome β”œβ”€β”€ GET /api/v1/health β†’ Health check β”œβ”€β”€ GET /api/v1/docs β†’ API docs └── /api/v1/contact β†’ contactRoutes └── POST /submit β†’ submitContactForm controller

Contact Form Flow

Client POST /api/v1/contact/submit β”‚ β”œβ”€β”€ Rate limiter check (3 req/hr) β”œβ”€β”€ Body parsed by express.json() β”‚ └── submitContactForm() β”œβ”€β”€ Validate required fields (name, email, phone, message) β”œβ”€β”€ Call sendContactEmail() β”‚ β”œβ”€β”€ Create Nodemailer transporter (Zoho SMTP, port 465) β”‚ β”œβ”€β”€ Build HTML email template β”‚ └── Send to ADMIN_EMAIL with replyTo set to visitor's email └── Return 200 { success: true }

Logger

Winston is configured with structured log levels (info, warn, error) and outputs to both console and rotating log files under ./logs/. Morgan streams HTTP logs through Winston's HTTP log stream.


πŸ”’ Security Features

Feature Implementation
Security Headers Helmet with full CSP, X-Frame: DENY, X-XSS-Protection
Rate Limiting express-rate-limit (general + strict contact limiter)
CORS Whitelisting Only specific origins allowed, credentials: true
Input Parsing Limit JSON and URL-encoded body max 10MB
Trust Proxy Enabled for accurate IP detection behind Render/Nginx
Error Sanitization Global error handler strips stack traces in production
Graceful Shutdown SIGTERM/SIGINT handling with 10s forced-exit fallback

🌍 Deployment

Frontend β†’ Vercel

# From /user directory
npm run build   # Generates /dist

# vercel.json handles SPA routing (rewrites /* β†’ /index.html)

Vercel Settings:

  • Framework: Vite
  • Build Command: npm run build
  • Output Directory: dist
  • Root Directory: user
  • Add VITE_API_BASE_URL in Vercel Environment Variables

Backend β†’ Render

Render Settings:

  • Environment: Node
  • Root Directory: server
  • Build Command: npm install && npm run build
  • Start Command: npm run start (runs node dist/index.js)
  • Add all required env variables from the Environment Variables section in Render dashboard

⚠️ Set CORS_ORIGIN on Render to your Vercel deployment URL to allow cross-origin requests.


🀝 Contributing

# 1. Fork the repository
# 2. Create a feature branch
git checkout -b feature/your-feature-name

# 3. Make changes, then commit
git commit -m "feat: add your feature description"

# 4. Push and open a Pull Request
git push origin feature/your-feature-name

Code Style:

  • Backend: ESLint + Prettier (TypeScript strict mode)
  • Frontend: ESLint with react-hooks and react-refresh plugins
  • Follow existing naming conventions (PascalCase components, camelCase utils)

Built with ❀️ by Vansh Sharma

About

Production-ready corporate compliance website built with Next.js 14, TypeScript, MongoDB and Tailwind CSS

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages