A full-featured e-commerce storefront for authentic Bangladeshi natural products — honey, dates, ghee, and more. Built as an educational redesign with React, Vite, Tailwind CSS, and Supabase.
Disclaimer: This is an independent redesign of the GhorerBazar website, built for educational and portfolio purposes only. It is not affiliated with, endorsed by, or connected to the original GhorerBazar business in any way.
All product names, brand names, and trademarks referenced in this project belong to their respective owners. Product images and content sourced from the original website remain the intellectual property of GhorerBazar and are used here solely to simulate a realistic e-commerce UI for learning purposes — not for any commercial use.
As stated in the original site's Terms of Use: content including text, images, and logos is the property of GhorerBazar and may not be used without permission. This project does not distribute, monetize, or publicly deploy any such content.
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, Tailwind CSS 4 |
| UI Components | HeadlessUI, Heroicons, Swiper, Sonner |
| Routing | React Router v7 |
| Backend / Database | Supabase (PostgreSQL, Auth, Storage) |
| Deployment | Vercel / Netlify (static) |
- Catalog — Browse products by category, brand, or flag (Best Selling, New Arrival). Pagination, search, and sidebar filters (category, brand, price range).
- Product Detail — Image gallery, description tabs, related products.
- Cart — Persistent cart via localStorage. Quantity controls, real-time subtotal, free-delivery threshold progress bar.
- Wishlist — Synced to Supabase for logged-in users; localStorage for guests.
- Checkout — District-aware delivery fee (Dhaka ৳80 / Outside ৳120). Supports Cash on Delivery and full payment via bKash/Nagad. Transaction ID or sender number verification.
- Authentication — Email/password login, OTP (magic link) login, phone number resolved to email.
- User Profile — View and edit name, phone, address. Order history.
- Contact Form — Submissions stored in Supabase
contact_messagestable. - Admin Panel — Separate auth session. Dashboard, orders management, product CRUD, hero banners, site settings.
- Site Settings — Admin-configurable announcement bar, payment numbers, delivery contact, discount thresholds — all live from Supabase without a redeploy.
src/
├── admin/ # Admin panel (separate auth, layout, pages)
├── components/
│ ├── catalog/ # CatalogGrid, FilterSidebar, SortBar
│ ├── home/ # HeroBanner, FeaturedTabs, CategoryGrid, PromoSection
│ ├── layout/ # Navbar, Footer, CartSidebar, Layout
│ ├── product/ # ProductCard, ProductCardSkeleton
│ └── ui/ # Badge, Spinner, FieldError, Skeleton
├── config/ # Shared constants (AOV_TARGET, delivery fees)
├── context/ # CartContext, WishlistContext, UserAuthContext, SettingsContext
├── data/ # DISTRICTS, THANAS lookup tables
├── lib/ # Supabase clients, products, orders, settings, banners
├── pages/ # HomePage, CatalogPage, ProductPage, CheckoutPage, etc.
└── utils/ # cn (classnames), fmt (currency), productHelpers, validation
database/
├── setup.sql # Full schema: tables, RLS, grants, RPCs, indexes
├── categories-brands.sql # Category and brand seed data
├── products.sql # Product seed data (75 products)
└── full-reset.sql # DROP + full rebuild in a single file (run in SQL Editor)
Create a .env file in the project root:
VITE_SUPABASE_URL=https://your-project-id.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
VITE_SUPABASE_SERVICE_ROLE_KEY=your-service-role-keyNever commit .env to version control. The service role key bypasses RLS — keep it out of any client-side bundle in production.
- Create a new Supabase project at supabase.com.
- Go to SQL Editor and run
database/full-reset.sql. This creates all tables, RLS policies, indexes, RPCs, and seeds default data. - Go to Authentication → Settings:
- Enable Email OTP (magic link) for OTP login.
- Go to Authentication → Users → Add user:
- Create the admin user (e.g.
[email protected]).
- Create the admin user (e.g.
- Update your
.envwith the project URL and keys from Settings → API.
| Table | Purpose |
|---|---|
products |
Product catalog |
categories |
Product categories with images |
brands |
Brand list |
profiles |
User profile data (mirrors auth.users metadata) |
orders |
Customer orders (guest + authenticated) |
wishlists |
Per-user wishlisted product slugs |
site_settings |
Key-value store for admin-configurable values |
contact_messages |
Contact form submissions |
| Function | Purpose |
|---|---|
phone_exists(p_phone) |
Check if a phone number is already registered |
get_email_by_phone(p_phone) |
Resolve phone to email for login |
create_profile(p_id, p_name, p_phone, p_email) |
Insert profile row post-signup (bypasses RLS) |
The project uses three separate Supabase clients to ensure clean session isolation:
| Client | File | Key | Purpose |
|---|---|---|---|
supabase |
src/lib/supabase.js |
Anon | User-facing auth and data |
supabaseAdminAuth |
src/lib/supabaseAdmin.js |
Anon, storageKey: gb_admin_auth |
Admin auth session (isolated) |
supabaseAdmin |
src/lib/supabaseAdmin.js |
Service role | Admin DB operations (bypasses RLS) |
# Install dependencies
npm install
# Start dev server
npm run dev
# Build for production
npm run build
# Preview production build
npm run previewThe following values are managed from the Admin → Settings panel and take effect immediately without a redeploy:
| Key | Default | Used by |
|---|---|---|
announcement |
Free delivery on orders above 1000 BDT | Navbar announcement bar |
announcement_on |
true |
Show/hide announcement bar |
threshold |
1000 |
Cart discount threshold (BDT) |
discount_amount |
0 |
Discount amount when threshold met |
phone |
— | Contact/footer phone number |
whatsapp |
— | WhatsApp link on product pages |
email |
— | Contact email |
address |
— | Business address on contact page |
bkash_number |
— | Payment number shown at checkout |
nagad_number |
— | Payment number shown at checkout |
| Zone | Fee |
|---|---|
| Inside Dhaka | ৳80 |
| Outside Dhaka | ৳120 |
Fees are defined in src/config/constants.js as DELIVERY_FEE_DHAKA and DELIVERY_FEE_OUTSIDE.
The app is a static SPA. Deploy to any static host (Vercel, Netlify, Cloudflare Pages).
Important: Configure your host to redirect all 404s to index.html so client-side routing works correctly.
Vercel — add a vercel.json:
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}Netlify — add a _redirects file in public/:
/* /index.html 200
Set all three VITE_* environment variables in your hosting provider's dashboard.
MIT License — see LICENSE for details.
Made by LittleFox. You are free to use, modify, and distribute this project as long as you include the original copyright notice and credit the author.

















