βββ βββ ββββββ βββββββββββ
βββ βββ βββββββββββββββββββ
βββ βββ βββ ββββββ ββββββ
βββ βββ βββ ββββββ ββββββ
βββββββββββββββββββββ βββββββββββ
ββββββββ βββββββ βββ βββββββββββ
A production-grade, full-stack clothing store built with Next.js 14
Inspired by Zara Β· H&M Β· Myntra Β· TotΓͺme
LUXE is a fully featured premium clothing store with real authentication, real payments, phone/email OTP verification, WhatsApp order fulfilment, and an editorial luxury design. Built for a real cloth shop wanting to digitise β zero compromise on quality.
Customer visits β Browses β Adds to cart β Logs in β Pays via Razorpay
β Order auto-sent to shop WhatsApp β Shop owner confirms β Done.
luxe-store/
β
βββ π app/ # Next.js 14 App Router
β βββ layout.jsx # Root layout β fonts, AuthProvider
β βββ page.jsx # Home page
β βββ globals.css # Tailwind base + custom utilities
β β
β βββ π shop/page.jsx # Shop β filters, sorting, grid
β βββ π product/[id]/page.jsx # Product detail β gallery, size/colour picker
β βββ π cart/page.jsx # Cart β live qty, free shipping bar
β βββ π checkout/page.jsx # Checkout β Razorpay + WhatsApp dispatch
β βββ π wishlist/page.jsx # Saved products
β βββ π login/page.jsx # Sign in β Email + Google OAuth
β βββ π signup/page.jsx # Sign up β with phone field + strength meter
β βββ π account/page.jsx # Dashboard β Email OTP + Phone OTP verify
β βββ π about/page.jsx # Brand story, team, timeline, press
β βββ π contact/page.jsx # Contact form + WhatsApp CTA + FAQs
β βββ π size-guide/page.jsx # Women / Men / Kids size tables
β βββ π shipping/page.jsx # Shipping options + returns policy
β βββ π order-tracking/page.jsx # Live order status by Order ID
β βββ π faqs/page.jsx # 25 FAQs β searchable, categorised
β β
β βββ π api/ # Next.js API Routes (backend)
β βββ π auth/
β β βββ sync-user/route.js # POST β Firebase β MongoDB upsert
β β βββ me/route.js # GET/PATCH β fetch/update profile
β β βββ send-email-otp/route.js # POST β generate + email 6-digit OTP
β β βββ verify-email-otp/route.js# POST β verify OTP, mark emailVerified
β β βββ verify-phone/route.js # POST β mark phoneVerified after SMS OTP
β βββ π create-order/route.js # POST β create Razorpay order (server-side)
β βββ π verify-payment/route.js # POST β HMAC signature verification
β
βββ π components/
β βββ π layout/
β β βββ Navbar.jsx # Sticky β search overlay, user dropdown, mobile drawer
β β βββ Footer.jsx # Newsletter, links, contact, socials
β βββ π sections/ # Home page sections
β β βββ HeroSection.jsx
β β βββ MarqueeBar.jsx
β β βββ CategoriesSection.jsx
β β βββ FeaturedSection.jsx
β β βββ TrendingSection.jsx
β β βββ PromoBanner.jsx
β β βββ TestimonialsSection.jsx
β β βββ InstagramSection.jsx
β βββ π ui/
β βββ ProductCard.jsx # Card β quick-add, wishlist, colour dots
β
βββ π contexts/
β βββ AuthContext.jsx # Global auth state β useAuth() hook
β
βββ π lib/
β βββ firebase.js # Firebase client SDK (browser)
β βββ firebaseAdmin.js # Firebase Admin SDK (server only)
β βββ mongodb.js # Mongoose connection with singleton pooling
β βββ products.js # 13 dummy products + SHOP_WHATSAPP config
β βββ store.js # Zustand β cart + wishlist (localStorage)
β
βββ π models/
β βββ User.js # Mongoose user schema
β βββ OtpToken.js # OTP schema with 10-min TTL auto-expiry
β
βββ .env.local # π All secrets (never committed)
βββ .env.example # Template for onboarding
βββ .gitignore
βββ next.config.js
βββ tailwind.config.js
βββ postcss.config.js
βββ package.json
| Feature | Details |
|---|---|
| Home Page | Hero banner, animated marquee, categories, featured, trending, promo splits, testimonials, Instagram grid |
| Shop Page | Filter by category / price / size / colour, live sort (newest, trending, price, rating) |
| Product Page | Multi-image gallery, size + colour selector, quantity picker, add-to-cart, WhatsApp enquiry |
| Cart | Real-time qty updates, free shipping progress bar, coupon input |
| Wishlist | Save/remove products, persisted via Zustand + localStorage |
| Search | Instant live overlay β searches name, category, description |
| Step | What happens |
|---|---|
| 1 | POST /api/create-order β server creates Razorpay order, returns order_id |
| 2 | Razorpay modal opens with order_id (card, UPI, net banking, wallets, EMI) |
| 3 | POST /api/verify-payment β HMAC signature verification on server |
| 4 | WhatsApp auto-opens with full order + Payment ID + Order ID |
| Method | Flow |
|---|---|
| Google OAuth | One-click Google sign-in β auto email-verified |
| Email / Password | Register with name, email, phone, password β email OTP verification |
| Forgot Password | Reset link sent via Firebase |
| Email OTP | 6-digit OTP via Gmail SMTP β marks emailVerified in MongoDB + Firebase |
| Phone OTP | SMS via Firebase PhoneAuthProvider β updatePhoneNumber on current user |
Click "Verify Email"
β POST /api/auth/send-email-otp
β 6-digit OTP generated, stored in MongoDB (TTL: 10 min, max attempts: 5)
β Branded HTML email sent via nodemailer (Gmail SMTP)
β Inline 6-box OTP input appears
User enters OTP
β POST /api/auth/verify-email-otp
β OTP checked, attempt counter enforced
β emailVerified = true in MongoDB + Firebase Admin SDK
β Green "Verified β" badge appears instantly
Click "Verify Now" / "Add & Verify"
β Invisible reCAPTCHA via Firebase
β PhoneAuthProvider.verifyPhoneNumber β SMS sent
β 6-box OTP input (auto-advance, auto-submit, paste support)
User enters OTP
β PhoneAuthProvider.credential(verificationId, code)
β updatePhoneNumber(auth.currentUser, credential)
β phoneVerified = true in MongoDB
β Green "Verified β" badge appears instantly
After Razorpay payment is confirmed, WhatsApp auto-opens with:
β
PAYMENT CONFIRMED β LUXE STORE
βββββββββββββββββββββ
π³ Payment ID: pay_Qx7mK9rTpLnW4z
π Order ID: order_XXXXXXXXXX
π€ CUSTOMER DETAILS
Name: Priya Sharma
Phone: 9876543210
Address: 23, Palm Grove, Mumbai β 400050
π§Ύ ORDER DETAILS
1. Ivory Linen Blazer
β’ Size: S β’ Colour: Ivory β’ Qty: 1 β’ βΉ4,299
π° GRAND TOTAL: βΉ6,997
- Node.js 18+
- A Firebase project
- A MongoDB Atlas cluster
- A Razorpay account
- A Gmail account (for email OTP)
git clone https://github.com/your-username/luxe-store.git
cd luxe-store
npm installCopy the template and fill in your values:
cp .env.example .env.localOpen .env.local:
# ββ RAZORPAY βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# dashboard.razorpay.com β Settings β API Keys
RAZORPAY_KEY_ID=rzp_test_XXXXXXXXXXXXXXXX
RAZORPAY_KEY_SECRET=XXXXXXXXXXXXXXXXXXXXXXXX
NEXT_PUBLIC_RAZORPAY_KEY_ID=rzp_test_XXXXXXXXXXXXXXXX
# ββ FIREBASE (Client β safe to expose) βββββββββββββββββββββββββββββββββββββββ
# console.firebase.google.com β Project Settings β Your Apps β Web
NEXT_PUBLIC_FIREBASE_API_KEY=AIzaSy...
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=123456789
NEXT_PUBLIC_FIREBASE_APP_ID=1:123456789:web:abc123
# ββ FIREBASE ADMIN (Server only β NEVER prefix with NEXT_PUBLIC_) βββββββββββββ
# console.firebase.google.com β Project Settings β Service Accounts β Generate Key
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk@your-project.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYOUR_KEY\n-----END PRIVATE KEY-----\n"
# ββ MONGODB βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# cloud.mongodb.com β Connect β Drivers
MONGODB_URI=mongodb+srv://user:pass@cluster0.xxxxx.mongodb.net/luxe_store
# ββ EMAIL / SMTP (for Email OTP) ββββββββββββββββββββββββββββββββββββββββββββββ
# Gmail App Password: myaccount.google.com β Security β App Passwords
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-gmail@gmail.com
SMTP_PASS=xxxx-xxxx-xxxx-xxxx- Go to console.firebase.google.com β your project
- Authentication β Sign-in method β Enable:
- β Email/Password
- β Google
- β Phone
- Authentication β Settings β Authorized domains β Add
localhost - Project Settings β Service Accounts β Generate new private key β download JSON β copy values to
.env.local
- Go to cloud.mongodb.com β your cluster
- Security β Network Access β Add IP Address β Allow Access From Anywhere (
0.0.0.0/0) - Security β Database Access β Create a user with Read and Write access
- Databases β Connect β Drivers β copy the connection string to
MONGODB_URI
- Go to myaccount.google.com β Security
- Enable 2-Step Verification (required)
- Search "App Passwords" β Select app: Mail β Generate
- Copy the 16-character password β paste into
SMTP_PASSin.env.local
Open lib/products.js:
export const SHOP_WHATSAPP = "919876543210"; // 91 + 10-digit numbernpm run dev # Development
npm run build # Production build
npm start # Start production serverOpen http://localhost:3000 π
| Element | Value |
|---|---|
| Display Font | Cormorant Garamond (300, 400, 500, 600, 700) |
| Body Font | DM Sans (300, 400, 500, 600) |
| Primary Palette | Stone 50β900, White, Champagne #f5ede0, Cream #faf8f5 |
| Style Direction | Editorial luxury β Zara Γ TotΓͺme Γ Brunello Cucinelli |
| Animation Library | Framer Motion 11 β stagger, fade-up, spring, presence |
| Icon Library | Lucide React |
| Layer | Technology |
|---|---|
| Framework | Next.js 14 (App Router) |
| UI | React 18 + Tailwind CSS 3 |
| Animation | Framer Motion 11 |
| Auth | Firebase Auth (Email, Google, Phone OTP) |
| Database | MongoDB Atlas + Mongoose |
| Payments | Razorpay (Cards, UPI, Net Banking, Wallets, EMI) |
| Nodemailer + Gmail SMTP | |
| State | Zustand 4 (cart + wishlist, persisted) |
| Icons | Lucide React |
Open lib/products.js and add to the products array:
{
id: "unique-id",
name: "Product Name",
category: "Women", // "Women" | "Men" | "Kids"
gender: "Women",
price: 2999,
originalPrice: 4000, // optional β shows discount badge
images: ["url1", "url2"],
sizes: ["XS", "S", "M", "L", "XL"],
colors: ["Black", "White"],
colorHex: { Black: "#1a1a1a", White: "#FFFFFF" },
description: "Product description...",
tag: "New Arrival", // "New Arrival" | "Bestseller" | "Trending"
trending: true,
featured: true,
rating: 4.8,
reviews: 120,
fabric: "100% Cotton",
care: "Machine wash cold",
}mkdir app/my-page && touch app/my-page/page.jsxImport Navbar and Footer from @/components/layout/ and you're live.
.env.localis in.gitignoreβ secrets are never committedFIREBASE_PRIVATE_KEYlives server-side only β never prefixed withNEXT_PUBLIC_RAZORPAY_KEY_SECRETlives server-side only β payment signatures verified on server- OTP attempts are capped at 5 per token β brute force protected
- OTP tokens auto-expire in 10 minutes via MongoDB TTL index
| Route | Page |
|---|---|
/ |
Home |
/shop |
Shop (filters + sorting) |
/product/[id] |
Product Detail |
/cart |
Shopping Cart |
/checkout |
Checkout + Razorpay |
/wishlist |
Wishlist |
/login |
Sign In |
/signup |
Create Account |
/account |
Account Dashboard |
/about |
About Us |
/contact |
Contact + FAQs |
/size-guide |
Size Guide |
/shipping |
Shipping & Returns |
/order-tracking |
Track Order |
/faqs |
Frequently Asked Questions |
MIT β free to use, modify, and deploy for commercial projects.
Built with β₯ for premium fashion retail
LUXE β Where every detail is intentional.