A professional B2B product exhibition website built on Cloudflare Workers with D1 database, R2 storage, and role-based admin system.
- Home Page - Company introduction and featured products showcase
- Products Page - Product listing with category filtering and search
- Product Detail Page - Detailed product information and inquiry form
- About Page - Company introduction, history, and certifications
- Contact Page - Contact information and online inquiry form
- Responsive Design - Optimized for mobile, tablet, and desktop devices
- Role-Based Access Control
- Super Admin - Full CRUD permissions (create, read, update, delete)
- Regular Admin - Read-only access (view only)
- Admin Dashboard - Statistical overview and data insights
- Product Management - Product listing, editing, deletion, and creation
- Image Upload - Support for uploading images to Cloudflare R2
- Inquiry Management - View, process, and delete customer inquiries
- Website Settings - Configure site information, contact details, and social media links (Super Admin only)
- Product API - Complete CRUD operations (GET/POST/PUT/DELETE)
- Inquiry API - Submit inquiries, query, and status updates
- Admin API - Login authentication, token verification, role management
- Image Upload API - Upload images to R2 storage
- Settings API - Manage website configuration via KV storage
- Products Table - Product information storage
- Inquiries Table - Customer inquiry records
- Admins Table - Admin accounts with role-based permissions
- Backend: Cloudflare Workers
- Database: Cloudflare D1 (SQLite)
- Storage: Cloudflare R2 (Images), Cloudflare KV (Settings)
- Frontend: HTML5, CSS3, JavaScript (Vanilla)
- Authentication: JWT tokens with SHA-256 password hashing
- Authorization: Role-based access control (RBAC)
Before you begin, ensure Node.js is installed on your system (version 16 or higher recommended).
Download and Install:
- Visit Node.js official website
- Download the LTS (Long Term Support) version
- Run the installer and follow the installation wizard
- Verify installation:
node --version
npm --versionnpm install# Create database
wrangler d1 create b2b_database
# Note the database_id from output and update wrangler.tomlEdit wrangler.toml and replace database_id with the actual ID from step 3:
[[d1_databases]]
binding = "DB"
database_name = "b2b_database"
database_id = "your-database-id" # Replace this# Create R2 bucket
wrangler r2 bucket create b2b-product-imagesConfirm wrangler.toml has R2 configuration:
[[r2_buckets]]
binding = "IMAGES"
bucket_name = "b2b-product-images"# Create KV namespace for production
wrangler kv namespace create "STATIC_ASSETS"
# Create KV namespace for development (optional)
wrangler kv namespace create "STATIC_ASSETS" --previewUpdate wrangler.toml with the KV namespace IDs:
[[kv_namespaces]]
binding = "STATIC_ASSETS"
id = "your-kv-namespace-id" # Replace this
preview_id = "your-preview-kv-namespace-id" # Optional, for local dev# Execute database schema
wrangler d1 execute b2b_database --file=./schema/schema.sqlThis will create:
- Database tables (products, inquiries, admins)
- Two default admin accounts:
- Super Admin: username
admin123, passwordadmin123 - Regular Admin: username
staff, passwordstaff123
- Super Admin: username
- Sample products for testing
npm run devVisit http://localhost:8787 to test the website.
Admin Login: Access http://localhost:8787/admin to log in.
npm run deployAfter initial setup, you'll have two admin accounts:
| Username | Password | Role | Permissions |
|---|---|---|---|
| admin123 | admin123 | Super Admin | Full CRUD access |
| staff | staff123 | Regular Admin | Read-only access |
🔐 IMPORTANT: Change default passwords immediately after first deployment!
Use browser console to generate a new password hash:
async function hashPassword(password) {
const encoder = new TextEncoder();
const data = encoder.encode(password);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
// Generate hash for your new password
hashPassword('your-new-secure-password').then(hash => console.log(hash));-- Update admin password
UPDATE admins
SET password_hash = 'your-generated-hash'
WHERE username = 'admin';Execute via Wrangler CLI:
wrangler d1 execute b2b_database --command="UPDATE admins SET password_hash = 'your-hash' WHERE username = 'admin';"Or via Cloudflare Dashboard Console.
Option A: Using wrangler.toml (not recommended for production)
[vars]
JWT_SECRET = "your-very-secure-secret-key-change-this"
ENVIRONMENT = "production"Option B: Using Cloudflare Dashboard Secrets (recommended)
wrangler secret put JWT_SECRET
# Enter your secret when prompted-
Browse Products
- Visit homepage to see featured products
- Navigate to Products page to browse all products
- Use category filters and search to find specific products
-
Submit Product Inquiry
- Click "Send Inquiry" on product detail page
- Fill out and submit the inquiry form
- Or submit general inquiry via Contact page
-
Login
- Visit
/adminor/admin/login - Use your admin credentials
- Visit
-
Manage Products (Super Admin only)
- View all products
- Edit product information
- Upload product images (JPEG, PNG, GIF, WebP, max 5MB)
- Delete unwanted products
- Add new products
-
Manage Inquiries
- View all customer inquiries (All admins)
- View inquiry details (All admins)
- Update inquiry status (All admins)
- Delete processed inquiries (Super Admin only)
-
Configure Settings (Super Admin only)
- Update website name and description
- Edit company introduction
- Modify contact information
- Set social media links
cf_b2b/
├── src/
│ ├── index.js # Workers entry point
│ ├── api/
│ │ ├── router.js # API routing
│ │ └── handlers/ # API handlers
│ │ ├── products.js # Product API
│ │ ├── inquiries.js # Inquiry API
│ │ ├── admin.js # Admin API
│ │ ├── upload.js # Image upload API
│ │ └── settings.js # Settings API
│ ├── pages/
│ │ ├── router.js # Page routing
│ │ ├── layout.js # Page layout template
│ │ ├── home.js # Homepage
│ │ ├── products.js # Product listing page
│ │ ├── product-detail.js # Product detail page
│ │ ├── about.js # About page
│ │ ├── contact.js # Contact page
│ │ ├── admin-login.js # Admin login page
│ │ ├── admin-dashboard.js# Admin dashboard
│ │ └── static.js # Static asset handler
│ └── utils/
│ └── auth.js # Authentication utilities
├── public/
│ ├── css/
│ │ └── main.css # Main stylesheet
│ └── js/
│ ├── main.js # Main JS file
│ └── admin.js # Admin dashboard JS
├── schema/
│ ├── schema.sql # Database schema
│ ├── init.sql # Initialization script
├── package.json
├── wrangler.toml # Cloudflare Workers config
├── README.md
└── DEPLOY.md
-
Database Connection Error
- Verify
database_idin wrangler.toml matches your D1 database - Ensure database schema has been initialized
- Verify
-
Image Upload Fails
- Confirm R2 bucket exists:
wrangler r2 bucket list - Check R2 binding name in wrangler.toml matches "IMAGES"
- Confirm R2 bucket exists:
-
Settings Not Saving
- Ensure KV namespace is created and bound
- Verify you're logged in as Super Admin
- Check browser console for errors
-
Login Issues
- Verify password hash is correct
- Check JWT_SECRET is configured
- Clear browser localStorage and try again
-
Permission Denied Errors
- Confirm your admin role (super_admin vs admin)
- Only super admins can create/update/delete
- Regular admins have read-only access
- 📧 Email Notifications - Send alerts for new inquiries
- 🔍 Enhanced Search - Full-text search functionality
- 📊 Analytics Dashboard - More detailed statistics and charts
- 🌐 Multi-language Support - I18n for global audiences
- 💾 Data Export - Export data to Excel/CSV
- 🔔 Real-time Notifications - WebSocket-based notifications
- 🖼️ Image Optimization - Auto-resize and compress images
- 📱 Mobile Admin App - Native mobile admin interface
For issues and questions:
- Check Wrangler CLI version:
wrangler --version - Verify D1 database initialization
- Review wrangler.toml configuration
- Check browser console for errors
- Review Cloudflare Workers logs
MIT