diff --git a/MONGODB_SETUP.md b/MONGODB_SETUP.md
new file mode 100644
index 0000000..9d67684
--- /dev/null
+++ b/MONGODB_SETUP.md
@@ -0,0 +1,286 @@
+# MongoDB Atlas Setup Guide for Welding Industry Website
+
+This guide will help you set up MongoDB Atlas and populate your welding industry website with data.
+
+## Prerequisites
+
+- MongoDB Atlas account (free tier available)
+- Node.js and npm installed
+- Next.js project setup
+
+## Step 1: Create MongoDB Atlas Cluster
+
+1. Go to [MongoDB Atlas](https://www.mongodb.com/atlas) and create a free account
+2. Create a new cluster:
+ - Choose the free tier (M0)
+ - Select your preferred cloud provider and region
+ - Name your cluster (e.g., "welding-company")
+
+3. Set up database access:
+ - Go to "Database Access" in the left sidebar
+ - Click "Add New Database User"
+ - Choose "Password" authentication
+ - Create a username and strong password
+ - Set database user privileges to "Read and write to any database"
+
+4. Set up network access:
+ - Go to "Network Access" in the left sidebar
+ - Click "Add IP Address"
+ - For development, you can add "0.0.0.0/0" (allow access from anywhere)
+ - For production, use specific IP addresses
+
+## Step 2: Get Connection String
+
+1. Go to "Clusters" and click "Connect" on your cluster
+2. Choose "Connect your application"
+3. Select "Node.js" as driver and version "4.1 or later"
+4. Copy the connection string (it looks like):
+ ```
+ mongodb+srv://username:password@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority
+ ```
+
+## Step 3: Configure Environment Variables
+
+1. Update your `.env.local` file with your actual MongoDB connection string:
+ ```env
+ MONGODB_URI=mongodb+srv://yourusername:yourpassword@cluster0.xxxxx.mongodb.net/welding-company?retryWrites=true&w=majority
+ ```
+
+ Replace:
+ - `yourusername` with your database username
+ - `yourpassword` with your database password
+ - `cluster0.xxxxx` with your actual cluster connection string
+ - `welding-company` with your preferred database name
+
+## Step 4: Install Dependencies
+
+The required packages are already installed:
+- `mongodb` - MongoDB driver
+- `mongoose` - ODM for MongoDB
+- `dotenv` - Environment variable loader
+
+## Step 5: Populate Database with Sample Data
+
+Run the seeding script to populate your database with sample welding industry data:
+
+```bash
+npm run seed
+```
+
+This will create sample data for:
+- **Products**: Welding equipment, safety gear, consumables
+- **Industries**: Automotive, Construction, Oil & Gas
+- **Training Courses**: MIG welding, TIG welding, Inspector certification
+- **Job Postings**: Various welding positions
+
+## Step 6: Verify Database Setup
+
+You can verify the setup by:
+
+1. Checking MongoDB Atlas dashboard to see your collections
+2. Testing API endpoints:
+ ```bash
+ # Start your development server
+ npm run dev
+
+ # Test endpoints (in another terminal or browser)
+ curl http://localhost:3000/api/products
+ curl http://localhost:3000/api/industries
+ curl http://localhost:3000/api/training
+ curl http://localhost:3000/api/jobs
+ ```
+
+## Database Schema Overview
+
+### Products Collection
+- **Fields**: name, category, description, specifications, price, images, inStock, featured, tags
+- **Categories**: welding-equipment, consumables, safety-gear, accessories
+
+### Industries Collection
+- **Fields**: name, slug, description, services, applications, image, caseStudies, featured
+
+### Training Courses Collection
+- **Fields**: title, slug, description, level, duration, price, curriculum, prerequisites, certification, instructor, schedule, featured
+
+### Job Postings Collection
+- **Fields**: title, department, location, type, experience, salary, description, responsibilities, requirements, benefits, skills, isActive, featured
+
+## API Endpoints
+
+### Products
+- `GET /api/products` - Get all products
+- `GET /api/products?category=welding-equipment` - Filter by category
+- `GET /api/products?featured=true` - Get featured products
+- `POST /api/products` - Create new product
+
+### Industries
+- `GET /api/industries` - Get all industries
+- `GET /api/industries?featured=true` - Get featured industries
+- `POST /api/industries` - Create new industry
+
+### Training
+- `GET /api/training` - Get all courses
+- `GET /api/training?level=beginner` - Filter by level
+- `GET /api/training?featured=true` - Get featured courses
+- `POST /api/training` - Create new course
+
+### Jobs
+- `GET /api/jobs` - Get all active jobs
+- `GET /api/jobs?department=Engineering` - Filter by department
+- `GET /api/jobs?featured=true` - Get featured jobs
+- `POST /api/jobs` - Create new job posting
+
+## Using Data in Your Components
+
+Here's how to fetch and use data in your Next.js components:
+
+### Example: Fetching Products
+
+```jsx
+// In a page or component
+import { useEffect, useState } from 'react'
+
+export default function ProductsPage() {
+ const [products, setProducts] = useState([])
+ const [loading, setLoading] = useState(true)
+
+ useEffect(() => {
+ const fetchProducts = async () => {
+ try {
+ const response = await fetch('/api/products?featured=true')
+ const data = await response.json()
+ if (data.success) {
+ setProducts(data.data)
+ }
+ } catch (error) {
+ console.error('Error fetching products:', error)
+ } finally {
+ setLoading(false)
+ }
+ }
+
+ fetchProducts()
+ }, [])
+
+ if (loading) return
Loading...
+
+ return (
+
+ {products.map((product) => (
+
+
{product.name}
+
{product.description}
+
${product.price}
+
+ ))}
+
+ )
+}
+```
+
+### Example: Server-Side Rendering
+
+```jsx
+// For server-side rendering (in pages/ directory)
+import { productOperations } from '@/lib/data-operations'
+
+export async function getServerSideProps() {
+ try {
+ const featuredProducts = await productOperations.getFeatured(6)
+
+ return {
+ props: {
+ products: JSON.parse(JSON.stringify(featuredProducts))
+ }
+ }
+ } catch (error) {
+ return {
+ props: {
+ products: []
+ }
+ }
+ }
+}
+
+export default function HomePage({ products }) {
+ return (
+
+
Featured Products
+ {/* Render products */}
+
+ )
+}
+```
+
+## Data Management Utilities
+
+Use the provided data operations for common tasks:
+
+```javascript
+import {
+ productOperations,
+ industryOperations,
+ trainingOperations,
+ jobOperations
+} from '@/lib/data-operations'
+
+// Examples
+const featuredProducts = await productOperations.getFeatured(4)
+const weldingEquipment = await productOperations.getByCategory('welding-equipment')
+const beginnerCourses = await trainingOperations.getByLevel('beginner')
+const engineeringJobs = await jobOperations.getByDepartment('Engineering')
+```
+
+## Production Considerations
+
+1. **Security**:
+ - Use specific IP addresses in Network Access for production
+ - Create separate database users for different environments
+ - Use strong passwords and rotate them regularly
+
+2. **Performance**:
+ - Add database indexes for frequently queried fields
+ - Use pagination for large result sets
+ - Implement caching strategies
+
+3. **Monitoring**:
+ - Set up MongoDB Atlas monitoring and alerts
+ - Monitor API endpoint performance
+ - Log database operations
+
+## Troubleshooting
+
+### Common Issues:
+
+1. **Connection Error**: Check your connection string and network access settings
+2. **Authentication Failed**: Verify username/password and database user permissions
+3. **No Data**: Run the seed script again or check if the data was created in MongoDB Atlas
+
+### Useful Commands:
+
+```bash
+# Re-seed database
+npm run seed
+
+# Check MongoDB connection
+node -e "require('dotenv').config({path:'.env.local'}); console.log(process.env.MONGODB_URI)"
+
+# Test database connection
+node -e "
+require('dotenv').config({path:'.env.local'});
+const mongoose = require('mongoose');
+mongoose.connect(process.env.MONGODB_URI)
+ .then(() => console.log('✅ Connected to MongoDB'))
+ .catch(err => console.error('❌ Connection failed:', err))
+"
+```
+
+## Next Steps
+
+1. Customize the data models to match your specific business requirements
+2. Add validation and error handling to your API endpoints
+3. Implement user authentication and authorization
+4. Add search and filtering capabilities
+5. Set up automated backups for production data
+
+For questions or issues, refer to the [MongoDB Atlas Documentation](https://docs.atlas.mongodb.com/) or [Mongoose Documentation](https://mongoosejs.com/).
\ No newline at end of file
diff --git a/app/api/industries/route.js b/app/api/industries/route.js
new file mode 100644
index 0000000..2a14224
--- /dev/null
+++ b/app/api/industries/route.js
@@ -0,0 +1,43 @@
+import { NextResponse } from 'next/server'
+import dbConnect from '@/lib/mongoose'
+import Industry from '@/lib/models/Industry'
+
+export async function GET(request) {
+ try {
+ await dbConnect()
+
+ const { searchParams } = new URL(request.url)
+ const featured = searchParams.get('featured')
+ const limit = parseInt(searchParams.get('limit')) || 0
+
+ let query = {}
+ if (featured === 'true') query.featured = true
+
+ const industries = await Industry.find(query)
+ .limit(limit)
+ .sort({ createdAt: -1 })
+
+ return NextResponse.json({ success: true, data: industries })
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: error.message },
+ { status: 500 }
+ )
+ }
+}
+
+export async function POST(request) {
+ try {
+ await dbConnect()
+
+ const body = await request.json()
+ const industry = await Industry.create(body)
+
+ return NextResponse.json({ success: true, data: industry }, { status: 201 })
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: error.message },
+ { status: 400 }
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/api/jobs/route.js b/app/api/jobs/route.js
new file mode 100644
index 0000000..68ce112
--- /dev/null
+++ b/app/api/jobs/route.js
@@ -0,0 +1,49 @@
+import { NextResponse } from 'next/server'
+import dbConnect from '@/lib/mongoose'
+import JobPosting from '@/lib/models/JobPosting'
+
+export async function GET(request) {
+ try {
+ await dbConnect()
+
+ const { searchParams } = new URL(request.url)
+ const department = searchParams.get('department')
+ const type = searchParams.get('type')
+ const featured = searchParams.get('featured')
+ const active = searchParams.get('active')
+ const limit = parseInt(searchParams.get('limit')) || 0
+
+ let query = {}
+ if (department) query.department = department
+ if (type) query.type = type
+ if (featured === 'true') query.featured = true
+ if (active !== null) query.isActive = active === 'true'
+
+ const jobs = await JobPosting.find(query)
+ .limit(limit)
+ .sort({ createdAt: -1 })
+
+ return NextResponse.json({ success: true, data: jobs })
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: error.message },
+ { status: 500 }
+ )
+ }
+}
+
+export async function POST(request) {
+ try {
+ await dbConnect()
+
+ const body = await request.json()
+ const job = await JobPosting.create(body)
+
+ return NextResponse.json({ success: true, data: job }, { status: 201 })
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: error.message },
+ { status: 400 }
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/api/products/route.js b/app/api/products/route.js
new file mode 100644
index 0000000..db4b8a6
--- /dev/null
+++ b/app/api/products/route.js
@@ -0,0 +1,45 @@
+import { NextResponse } from 'next/server'
+import dbConnect from '@/lib/mongoose'
+import Product from '@/lib/models/Product'
+
+export async function GET(request) {
+ try {
+ await dbConnect()
+
+ const { searchParams } = new URL(request.url)
+ const category = searchParams.get('category')
+ const featured = searchParams.get('featured')
+ const limit = parseInt(searchParams.get('limit')) || 0
+
+ let query = {}
+ if (category) query.category = category
+ if (featured === 'true') query.featured = true
+
+ const products = await Product.find(query)
+ .limit(limit)
+ .sort({ createdAt: -1 })
+
+ return NextResponse.json({ success: true, data: products })
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: error.message },
+ { status: 500 }
+ )
+ }
+}
+
+export async function POST(request) {
+ try {
+ await dbConnect()
+
+ const body = await request.json()
+ const product = await Product.create(body)
+
+ return NextResponse.json({ success: true, data: product }, { status: 201 })
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: error.message },
+ { status: 400 }
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/api/training/route.js b/app/api/training/route.js
new file mode 100644
index 0000000..69098aa
--- /dev/null
+++ b/app/api/training/route.js
@@ -0,0 +1,45 @@
+import { NextResponse } from 'next/server'
+import dbConnect from '@/lib/mongoose'
+import TrainingCourse from '@/lib/models/TrainingCourse'
+
+export async function GET(request) {
+ try {
+ await dbConnect()
+
+ const { searchParams } = new URL(request.url)
+ const level = searchParams.get('level')
+ const featured = searchParams.get('featured')
+ const limit = parseInt(searchParams.get('limit')) || 0
+
+ let query = {}
+ if (level) query.level = level
+ if (featured === 'true') query.featured = true
+
+ const courses = await TrainingCourse.find(query)
+ .limit(limit)
+ .sort({ createdAt: -1 })
+
+ return NextResponse.json({ success: true, data: courses })
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: error.message },
+ { status: 500 }
+ )
+ }
+}
+
+export async function POST(request) {
+ try {
+ await dbConnect()
+
+ const body = await request.json()
+ const course = await TrainingCourse.create(body)
+
+ return NextResponse.json({ success: true, data: course }, { status: 201 })
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: error.message },
+ { status: 400 }
+ )
+ }
+}
\ No newline at end of file
diff --git a/lib/data-operations.js b/lib/data-operations.js
new file mode 100644
index 0000000..bba7873
--- /dev/null
+++ b/lib/data-operations.js
@@ -0,0 +1,239 @@
+import dbConnect from './mongoose'
+import Product from './models/Product'
+import Industry from './models/Industry'
+import TrainingCourse from './models/TrainingCourse'
+import JobPosting from './models/JobPosting'
+
+// Product operations
+export const productOperations = {
+ // Get all products with optional filters
+ async getAll(filters = {}) {
+ await dbConnect()
+ return await Product.find(filters).sort({ createdAt: -1 })
+ },
+
+ // Get featured products
+ async getFeatured(limit = 4) {
+ await dbConnect()
+ return await Product.find({ featured: true }).limit(limit)
+ },
+
+ // Get products by category
+ async getByCategory(category, limit = 0) {
+ await dbConnect()
+ return await Product.find({ category }).limit(limit)
+ },
+
+ // Create new product
+ async create(productData) {
+ await dbConnect()
+ return await Product.create(productData)
+ },
+
+ // Update product
+ async update(id, updateData) {
+ await dbConnect()
+ return await Product.findByIdAndUpdate(id, updateData, { new: true })
+ },
+
+ // Delete product
+ async delete(id) {
+ await dbConnect()
+ return await Product.findByIdAndDelete(id)
+ }
+}
+
+// Industry operations
+export const industryOperations = {
+ // Get all industries
+ async getAll() {
+ await dbConnect()
+ return await Industry.find({}).sort({ createdAt: -1 })
+ },
+
+ // Get featured industries
+ async getFeatured(limit = 3) {
+ await dbConnect()
+ return await Industry.find({ featured: true }).limit(limit)
+ },
+
+ // Get industry by slug
+ async getBySlug(slug) {
+ await dbConnect()
+ return await Industry.findOne({ slug })
+ },
+
+ // Create new industry
+ async create(industryData) {
+ await dbConnect()
+ return await Industry.create(industryData)
+ },
+
+ // Update industry
+ async update(id, updateData) {
+ await dbConnect()
+ return await Industry.findByIdAndUpdate(id, updateData, { new: true })
+ }
+}
+
+// Training course operations
+export const trainingOperations = {
+ // Get all courses with optional filters
+ async getAll(filters = {}) {
+ await dbConnect()
+ return await TrainingCourse.find(filters).sort({ createdAt: -1 })
+ },
+
+ // Get featured courses
+ async getFeatured(limit = 3) {
+ await dbConnect()
+ return await TrainingCourse.find({ featured: true }).limit(limit)
+ },
+
+ // Get courses by level
+ async getByLevel(level) {
+ await dbConnect()
+ return await TrainingCourse.find({ level })
+ },
+
+ // Get course by slug
+ async getBySlug(slug) {
+ await dbConnect()
+ return await TrainingCourse.findOne({ slug })
+ },
+
+ // Create new course
+ async create(courseData) {
+ await dbConnect()
+ return await TrainingCourse.create(courseData)
+ },
+
+ // Update course
+ async update(id, updateData) {
+ await dbConnect()
+ return await TrainingCourse.findByIdAndUpdate(id, updateData, { new: true })
+ },
+
+ // Enroll student in course schedule
+ async enrollStudent(courseId, scheduleIndex) {
+ await dbConnect()
+ const course = await TrainingCourse.findById(courseId)
+ if (course && course.schedule[scheduleIndex]) {
+ course.schedule[scheduleIndex].enrolledStudents += 1
+ return await course.save()
+ }
+ throw new Error('Course or schedule not found')
+ }
+}
+
+// Job posting operations
+export const jobOperations = {
+ // Get all active jobs
+ async getActive(filters = {}) {
+ await dbConnect()
+ return await JobPosting.find({ isActive: true, ...filters }).sort({ createdAt: -1 })
+ },
+
+ // Get featured jobs
+ async getFeatured(limit = 3) {
+ await dbConnect()
+ return await JobPosting.find({ featured: true, isActive: true }).limit(limit)
+ },
+
+ // Get jobs by department
+ async getByDepartment(department) {
+ await dbConnect()
+ return await JobPosting.find({ department, isActive: true })
+ },
+
+ // Get jobs by type
+ async getByType(type) {
+ await dbConnect()
+ return await JobPosting.find({ type, isActive: true })
+ },
+
+ // Create new job posting
+ async create(jobData) {
+ await dbConnect()
+ return await JobPosting.create(jobData)
+ },
+
+ // Update job posting
+ async update(id, updateData) {
+ await dbConnect()
+ return await JobPosting.findByIdAndUpdate(id, updateData, { new: true })
+ },
+
+ // Deactivate job posting
+ async deactivate(id) {
+ await dbConnect()
+ return await JobPosting.findByIdAndUpdate(id, { isActive: false }, { new: true })
+ }
+}
+
+// General utility functions
+export const generalOperations = {
+ // Get dashboard stats
+ async getDashboardStats() {
+ await dbConnect()
+
+ const [productCount, industryCount, courseCount, activeJobCount] = await Promise.all([
+ Product.countDocuments(),
+ Industry.countDocuments(),
+ TrainingCourse.countDocuments(),
+ JobPosting.countDocuments({ isActive: true })
+ ])
+
+ return {
+ products: productCount,
+ industries: industryCount,
+ courses: courseCount,
+ activeJobs: activeJobCount
+ }
+ },
+
+ // Search across all collections
+ async globalSearch(searchTerm) {
+ await dbConnect()
+
+ const searchRegex = new RegExp(searchTerm, 'i')
+
+ const [products, industries, courses, jobs] = await Promise.all([
+ Product.find({
+ $or: [
+ { name: searchRegex },
+ { description: searchRegex },
+ { tags: { $in: [searchRegex] } }
+ ]
+ }).limit(5),
+ Industry.find({
+ $or: [
+ { name: searchRegex },
+ { description: searchRegex },
+ { services: { $in: [searchRegex] } }
+ ]
+ }).limit(5),
+ TrainingCourse.find({
+ $or: [
+ { title: searchRegex },
+ { description: searchRegex }
+ ]
+ }).limit(5),
+ JobPosting.find({
+ isActive: true,
+ $or: [
+ { title: searchRegex },
+ { description: searchRegex },
+ { skills: { $in: [searchRegex] } }
+ ]
+ }).limit(5)
+ ])
+
+ return {
+ products,
+ industries,
+ courses,
+ jobs
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/models/Industry.js b/lib/models/Industry.js
new file mode 100644
index 0000000..53a0be5
--- /dev/null
+++ b/lib/models/Industry.js
@@ -0,0 +1,41 @@
+import mongoose from 'mongoose'
+
+const IndustrySchema = new mongoose.Schema({
+ name: {
+ type: String,
+ required: true,
+ trim: true
+ },
+ slug: {
+ type: String,
+ required: true,
+ unique: true
+ },
+ description: {
+ type: String,
+ required: true
+ },
+ services: [{
+ type: String
+ }],
+ applications: [{
+ type: String
+ }],
+ image: {
+ type: String
+ },
+ caseStudies: [{
+ title: String,
+ description: String,
+ image: String,
+ results: String
+ }],
+ featured: {
+ type: Boolean,
+ default: false
+ }
+}, {
+ timestamps: true
+})
+
+export default mongoose.models.Industry || mongoose.model('Industry', IndustrySchema)
\ No newline at end of file
diff --git a/lib/models/JobPosting.js b/lib/models/JobPosting.js
new file mode 100644
index 0000000..9548345
--- /dev/null
+++ b/lib/models/JobPosting.js
@@ -0,0 +1,63 @@
+import mongoose from 'mongoose'
+
+const JobPostingSchema = new mongoose.Schema({
+ title: {
+ type: String,
+ required: true,
+ trim: true
+ },
+ department: {
+ type: String,
+ required: true
+ },
+ location: {
+ type: String,
+ required: true
+ },
+ type: {
+ type: String,
+ required: true,
+ enum: ['full-time', 'part-time', 'contract', 'temporary']
+ },
+ experience: {
+ type: String,
+ required: true,
+ enum: ['entry-level', '1-3 years', '3-5 years', '5+ years']
+ },
+ salary: {
+ min: Number,
+ max: Number,
+ currency: { type: String, default: 'USD' }
+ },
+ description: {
+ type: String,
+ required: true
+ },
+ responsibilities: [{
+ type: String
+ }],
+ requirements: [{
+ type: String
+ }],
+ benefits: [{
+ type: String
+ }],
+ skills: [{
+ type: String
+ }],
+ isActive: {
+ type: Boolean,
+ default: true
+ },
+ applicationDeadline: {
+ type: Date
+ },
+ featured: {
+ type: Boolean,
+ default: false
+ }
+}, {
+ timestamps: true
+})
+
+export default mongoose.models.JobPosting || mongoose.model('JobPosting', JobPostingSchema)
\ No newline at end of file
diff --git a/lib/models/Product.js b/lib/models/Product.js
new file mode 100644
index 0000000..28d9904
--- /dev/null
+++ b/lib/models/Product.js
@@ -0,0 +1,44 @@
+import mongoose from 'mongoose'
+
+const ProductSchema = new mongoose.Schema({
+ name: {
+ type: String,
+ required: true,
+ trim: true
+ },
+ category: {
+ type: String,
+ required: true,
+ enum: ['welding-equipment', 'consumables', 'safety-gear', 'accessories']
+ },
+ description: {
+ type: String,
+ required: true
+ },
+ specifications: {
+ type: Object,
+ default: {}
+ },
+ price: {
+ type: Number,
+ required: true
+ },
+ images: [{
+ type: String
+ }],
+ inStock: {
+ type: Boolean,
+ default: true
+ },
+ featured: {
+ type: Boolean,
+ default: false
+ },
+ tags: [{
+ type: String
+ }]
+}, {
+ timestamps: true
+})
+
+export default mongoose.models.Product || mongoose.model('Product', ProductSchema)
\ No newline at end of file
diff --git a/lib/models/TrainingCourse.js b/lib/models/TrainingCourse.js
new file mode 100644
index 0000000..a4d406b
--- /dev/null
+++ b/lib/models/TrainingCourse.js
@@ -0,0 +1,64 @@
+import mongoose from 'mongoose'
+
+const TrainingCourseSchema = new mongoose.Schema({
+ title: {
+ type: String,
+ required: true,
+ trim: true
+ },
+ slug: {
+ type: String,
+ required: true,
+ unique: true
+ },
+ description: {
+ type: String,
+ required: true
+ },
+ level: {
+ type: String,
+ required: true,
+ enum: ['beginner', 'intermediate', 'advanced']
+ },
+ duration: {
+ type: String,
+ required: true
+ },
+ price: {
+ type: Number,
+ required: true
+ },
+ curriculum: [{
+ module: String,
+ topics: [String]
+ }],
+ prerequisites: [{
+ type: String
+ }],
+ certification: {
+ type: String
+ },
+ instructor: {
+ name: String,
+ bio: String,
+ image: String
+ },
+ schedule: [{
+ startDate: Date,
+ endDate: Date,
+ location: String,
+ maxStudents: Number,
+ enrolledStudents: { type: Number, default: 0 }
+ }],
+ image: {
+ type: String
+ },
+ featured: {
+ type: Boolean,
+ default: false
+ }
+}, {
+ timestamps: true
+})
+
+export default mongoose.models.TrainingCourse || mongoose.model('TrainingCourse', TrainingCourseSchema)
\ No newline at end of file
diff --git a/lib/mongodb.js b/lib/mongodb.js
new file mode 100644
index 0000000..6e56eed
--- /dev/null
+++ b/lib/mongodb.js
@@ -0,0 +1,29 @@
+import { MongoClient } from 'mongodb'
+
+const uri = process.env.MONGODB_URI
+const options = {}
+
+let client
+let clientPromise
+
+if (!process.env.MONGODB_URI) {
+ throw new Error('Please add your Mongo URI to .env.local')
+}
+
+if (process.env.NODE_ENV === 'development') {
+ // In development mode, use a global variable so that the value
+ // is preserved across module reloads caused by HMR (Hot Module Replacement).
+ if (!global._mongoClientPromise) {
+ client = new MongoClient(uri, options)
+ global._mongoClientPromise = client.connect()
+ }
+ clientPromise = global._mongoClientPromise
+} else {
+ // In production mode, it's best to not use a global variable.
+ client = new MongoClient(uri, options)
+ clientPromise = client.connect()
+}
+
+// Export a module-scoped MongoClient promise. By doing this in a
+// separate module, the client can be shared across functions.
+export default clientPromise
\ No newline at end of file
diff --git a/lib/mongoose.js b/lib/mongoose.js
new file mode 100644
index 0000000..8c2065f
--- /dev/null
+++ b/lib/mongoose.js
@@ -0,0 +1,47 @@
+import mongoose from 'mongoose'
+
+const MONGODB_URI = process.env.MONGODB_URI
+
+if (!MONGODB_URI) {
+ throw new Error(
+ 'Please define the MONGODB_URI environment variable inside .env.local'
+ )
+}
+
+/**
+ * Global is used here to maintain a cached connection across hot reloads
+ * in development. This prevents connections growing exponentially
+ * during API Route usage.
+ */
+let cached = global.mongoose
+
+if (!cached) {
+ cached = global.mongoose = { conn: null, promise: null }
+}
+
+async function dbConnect() {
+ if (cached.conn) {
+ return cached.conn
+ }
+
+ if (!cached.promise) {
+ const opts = {
+ bufferCommands: false,
+ }
+
+ cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
+ return mongoose
+ })
+ }
+
+ try {
+ cached.conn = await cached.promise
+ } catch (e) {
+ cached.promise = null
+ throw e
+ }
+
+ return cached.conn
+}
+
+export default dbConnect
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 5cd9983..8b69f91 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,9 @@
"version": "0.1.0",
"dependencies": {
"@heroicons/react": "^2.2.0",
+ "dotenv": "^17.2.1",
+ "mongodb": "^6.18.0",
+ "mongoose": "^8.17.0",
"next": "^14.2.30",
"nodemailer": "^6.10.1",
"react": "^18",
@@ -258,6 +261,15 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@mongodb-js/saslprep": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.0.tgz",
+ "integrity": "sha512-zlayKCsIjYb7/IdfqxorK5+xUMyi4vOKcFy10wKJYc63NSdKI8mNME+uJqfatkPmOSMMUiojrL58IePKBm3gvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "sparse-bitfield": "^3.0.3"
+ }
+ },
"node_modules/@napi-rs/wasm-runtime": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz",
@@ -589,6 +601,21 @@
"@types/react": "^18.0.0"
}
},
+ "node_modules/@types/webidl-conversions": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
+ "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/whatwg-url": {
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
+ "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/webidl-conversions": "*"
+ }
+ },
"node_modules/@typescript-eslint/parser": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
@@ -1406,6 +1433,15 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/bson": {
+ "version": "6.10.4",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz",
+ "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.20.1"
+ }
+ },
"node_modules/busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -1691,7 +1727,6 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
- "dev": true,
"dependencies": {
"ms": "^2.1.3"
},
@@ -1783,6 +1818,18 @@
"node": ">=6.0.0"
}
},
+ "node_modules/dotenv": {
+ "version": "17.2.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz",
+ "integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -3508,6 +3555,15 @@
"node": ">=4.0"
}
},
+ "node_modules/kareem": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
+ "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -3616,6 +3672,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/memory-pager": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+ "license": "MIT"
+ },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -3671,11 +3733,109 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/mongodb": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.18.0.tgz",
+ "integrity": "sha512-fO5ttN9VC8P0F5fqtQmclAkgXZxbIkYRTUi1j8JO6IYwvamkhtYDilJr35jOPELR49zqCJgXZWwCtW7B+TM8vQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@mongodb-js/saslprep": "^1.1.9",
+ "bson": "^6.10.4",
+ "mongodb-connection-string-url": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.20.1"
+ },
+ "peerDependencies": {
+ "@aws-sdk/credential-providers": "^3.188.0",
+ "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
+ "gcp-metadata": "^5.2.0",
+ "kerberos": "^2.0.1",
+ "mongodb-client-encryption": ">=6.0.0 <7",
+ "snappy": "^7.2.2",
+ "socks": "^2.7.1"
+ },
+ "peerDependenciesMeta": {
+ "@aws-sdk/credential-providers": {
+ "optional": true
+ },
+ "@mongodb-js/zstd": {
+ "optional": true
+ },
+ "gcp-metadata": {
+ "optional": true
+ },
+ "kerberos": {
+ "optional": true
+ },
+ "mongodb-client-encryption": {
+ "optional": true
+ },
+ "snappy": {
+ "optional": true
+ },
+ "socks": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/mongodb-connection-string-url": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz",
+ "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/whatwg-url": "^11.0.2",
+ "whatwg-url": "^14.1.0 || ^13.0.0"
+ }
+ },
+ "node_modules/mongoose": {
+ "version": "8.17.0",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.17.0.tgz",
+ "integrity": "sha512-mxW6TBPHViORfNYOFXCVOnT4d5aRr+CgDxTs1ViYXfuHzNpkelgJQrQa+Lz6hofoEQISnKlXv1L3ZnHyJRkhfA==",
+ "license": "MIT",
+ "dependencies": {
+ "bson": "^6.10.4",
+ "kareem": "2.6.3",
+ "mongodb": "~6.18.0",
+ "mpath": "0.9.0",
+ "mquery": "5.0.0",
+ "ms": "2.1.3",
+ "sift": "17.1.3"
+ },
+ "engines": {
+ "node": ">=16.20.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mongoose"
+ }
+ },
+ "node_modules/mpath": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz",
+ "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/mquery": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz",
+ "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "4.x"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/mz": {
"version": "2.7.0",
@@ -4272,7 +4432,6 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
"engines": {
"node": ">=6"
}
@@ -4689,6 +4848,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/sift": {
+ "version": "17.1.3",
+ "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz",
+ "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==",
+ "license": "MIT"
+ },
"node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
@@ -4720,6 +4885,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/sparse-bitfield": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+ "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
+ "license": "MIT",
+ "dependencies": {
+ "memory-pager": "^1.0.2"
+ }
+ },
"node_modules/stable-hash": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz",
@@ -5275,6 +5449,18 @@
"node": ">=8.0"
}
},
+ "node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/ts-api-utils": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
@@ -5529,6 +5715,28 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
diff --git a/package.json b/package.json
index 686abdb..77feb2f 100644
--- a/package.json
+++ b/package.json
@@ -6,10 +6,14 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
- "lint": "next lint"
+ "lint": "next lint",
+ "seed": "node scripts/seed-data.js"
},
"dependencies": {
"@heroicons/react": "^2.2.0",
+ "dotenv": "^17.2.1",
+ "mongodb": "^6.18.0",
+ "mongoose": "^8.17.0",
"next": "^14.2.30",
"nodemailer": "^6.10.1",
"react": "^18",
diff --git a/scripts/seed-data.js b/scripts/seed-data.js
new file mode 100644
index 0000000..b76383a
--- /dev/null
+++ b/scripts/seed-data.js
@@ -0,0 +1,431 @@
+require('dotenv').config({ path: '.env.local' })
+const mongoose = require('mongoose')
+
+// Import models
+const Product = require('../lib/models/Product.js').default
+const Industry = require('../lib/models/Industry.js').default
+const TrainingCourse = require('../lib/models/TrainingCourse.js').default
+const JobPosting = require('../lib/models/JobPosting.js').default
+
+const seedData = async () => {
+ try {
+ // Connect to MongoDB
+ await mongoose.connect(process.env.MONGODB_URI)
+ console.log('Connected to MongoDB')
+
+ // Clear existing data
+ await Product.deleteMany({})
+ await Industry.deleteMany({})
+ await TrainingCourse.deleteMany({})
+ await JobPosting.deleteMany({})
+ console.log('Cleared existing data')
+
+ // Seed Products
+ const products = [
+ {
+ name: "MIG-250 Professional Welder",
+ category: "welding-equipment",
+ description: "High-performance MIG welder suitable for industrial applications. Features digital display, precise arc control, and robust construction.",
+ specifications: {
+ amperage: "30-250A",
+ voltage: "220V/440V",
+ duty_cycle: "60% at 250A",
+ weight: "85 lbs"
+ },
+ price: 2499.99,
+ images: ["/images/mig-250.jpg"],
+ featured: true,
+ tags: ["MIG", "professional", "industrial"]
+ },
+ {
+ name: "TIG-200 Precision Welder",
+ category: "welding-equipment",
+ description: "Precision TIG welder perfect for detailed work on stainless steel and aluminum. AC/DC capability with pulse control.",
+ specifications: {
+ amperage: "5-200A",
+ voltage: "220V",
+ duty_cycle: "35% at 200A",
+ weight: "45 lbs"
+ },
+ price: 1899.99,
+ images: ["/images/tig-200.jpg"],
+ featured: true,
+ tags: ["TIG", "precision", "aluminum"]
+ },
+ {
+ name: "Premium Safety Helmet",
+ category: "safety-gear",
+ description: "Auto-darkening welding helmet with panoramic view and multiple arc sensors for optimal protection.",
+ specifications: {
+ shade_range: "9-13",
+ switching_time: "1/25000s",
+ sensor_count: 4,
+ weight: "1.8 lbs"
+ },
+ price: 299.99,
+ images: ["/images/safety-helmet.jpg"],
+ featured: false,
+ tags: ["safety", "auto-darkening", "protection"]
+ },
+ {
+ name: "ER70S-6 Welding Wire",
+ category: "consumables",
+ description: "High-quality carbon steel welding wire for MIG welding. Excellent arc stability and minimal spatter.",
+ specifications: {
+ diameter: "0.035 inch",
+ weight: "44 lbs",
+ material: "Carbon Steel",
+ aws_class: "ER70S-6"
+ },
+ price: 89.99,
+ images: ["/images/welding-wire.jpg"],
+ featured: false,
+ tags: ["consumables", "MIG", "carbon-steel"]
+ }
+ ]
+
+ const createdProducts = await Product.insertMany(products)
+ console.log(`Seeded ${createdProducts.length} products`)
+
+ // Seed Industries
+ const industries = [
+ {
+ name: "Automotive Manufacturing",
+ slug: "automotive-manufacturing",
+ description: "Comprehensive welding solutions for automotive assembly lines, chassis fabrication, and component manufacturing.",
+ services: [
+ "Assembly line welding automation",
+ "Chassis and frame welding",
+ "Exhaust system fabrication",
+ "Body panel joining",
+ "Quality control and inspection"
+ ],
+ applications: [
+ "Robotic welding systems",
+ "Spot welding for body assembly",
+ "MIG welding for structural components",
+ "Laser welding for precision parts"
+ ],
+ image: "/images/automotive-industry.jpg",
+ featured: true,
+ caseStudies: [
+ {
+ title: "Major Auto Plant Automation",
+ description: "Implemented robotic welding system for SUV production line",
+ results: "40% increase in production efficiency"
+ }
+ ]
+ },
+ {
+ name: "Construction & Infrastructure",
+ slug: "construction-infrastructure",
+ description: "Heavy-duty welding services for bridges, buildings, and infrastructure projects requiring certified structural welding.",
+ services: [
+ "Structural steel welding",
+ "Bridge construction",
+ "High-rise building framework",
+ "Pipeline installation",
+ "Certified welding procedures"
+ ],
+ applications: [
+ "Arc welding for structural steel",
+ "Flux-cored welding for outdoor projects",
+ "Stick welding for heavy sections",
+ "Submerged arc welding for thick materials"
+ ],
+ image: "/images/construction-industry.jpg",
+ featured: true,
+ caseStudies: [
+ {
+ title: "Downtown Bridge Project",
+ description: "Complete welding services for 500ft steel bridge construction",
+ results: "Project completed 2 weeks ahead of schedule"
+ }
+ ]
+ },
+ {
+ name: "Oil & Gas",
+ slug: "oil-gas",
+ description: "Specialized welding services for oil refineries, pipelines, and offshore platforms with strict safety and quality standards.",
+ services: [
+ "Pipeline welding and repair",
+ "Pressure vessel fabrication",
+ "Offshore platform construction",
+ "Refinery maintenance",
+ "API certified procedures"
+ ],
+ applications: [
+ "Pipeline welding with X-ray testing",
+ "Stainless steel for chemical processing",
+ "Underwater welding capabilities",
+ "High-pressure system fabrication"
+ ],
+ image: "/images/oil-gas-industry.jpg",
+ featured: true
+ }
+ ]
+
+ const createdIndustries = await Industry.insertMany(industries)
+ console.log(`Seeded ${createdIndustries.length} industries`)
+
+ // Seed Training Courses
+ const trainingCourses = [
+ {
+ title: "Basic MIG Welding Fundamentals",
+ slug: "basic-mig-welding",
+ description: "Learn the fundamentals of MIG welding including safety, equipment setup, and basic techniques. Perfect for beginners entering the welding field.",
+ level: "beginner",
+ duration: "40 hours (1 week)",
+ price: 899.99,
+ curriculum: [
+ {
+ module: "Safety and PPE",
+ topics: ["Welding safety fundamentals", "Personal protective equipment", "Workshop safety procedures"]
+ },
+ {
+ module: "Equipment Basics",
+ topics: ["MIG welder components", "Gas selection", "Wire selection", "Equipment maintenance"]
+ },
+ {
+ module: "Welding Techniques",
+ topics: ["Basic joint types", "Travel speed", "Gun angle", "Arc length control"]
+ }
+ ],
+ prerequisites: ["High school diploma or equivalent", "Basic math skills"],
+ certification: "AWS D1.1 Basic MIG Certification",
+ instructor: {
+ name: "Mike Rodriguez",
+ bio: "Certified Welding Inspector with 15 years of industrial experience",
+ image: "/images/instructor-mike.jpg"
+ },
+ schedule: [
+ {
+ startDate: new Date('2024-02-05'),
+ endDate: new Date('2024-02-09'),
+ location: "Main Training Center",
+ maxStudents: 12,
+ enrolledStudents: 8
+ }
+ ],
+ image: "/images/mig-training.jpg",
+ featured: true
+ },
+ {
+ title: "Advanced TIG Welding Mastery",
+ slug: "advanced-tig-welding",
+ description: "Master advanced TIG welding techniques for stainless steel and aluminum. Learn precision control and exotic material welding.",
+ level: "advanced",
+ duration: "80 hours (2 weeks)",
+ price: 1899.99,
+ curriculum: [
+ {
+ module: "Advanced Materials",
+ topics: ["Stainless steel welding", "Aluminum techniques", "Exotic alloys", "Dissimilar metal joining"]
+ },
+ {
+ module: "Precision Techniques",
+ topics: ["Pulse welding", "Walking the cup", "Freehand techniques", "Orbital welding"]
+ },
+ {
+ module: "Quality Control",
+ topics: ["Visual inspection", "Penetrant testing", "X-ray interpretation", "Weld defect analysis"]
+ }
+ ],
+ prerequisites: ["Basic TIG welding experience", "AWS D17.1 certification recommended"],
+ certification: "AWS D17.1 Advanced TIG Certification",
+ instructor: {
+ name: "Sarah Chen",
+ bio: "Master welder specializing in aerospace and nuclear applications",
+ image: "/images/instructor-sarah.jpg"
+ },
+ schedule: [
+ {
+ startDate: new Date('2024-02-12'),
+ endDate: new Date('2024-02-23'),
+ location: "Advanced Training Lab",
+ maxStudents: 8,
+ enrolledStudents: 5
+ }
+ ],
+ image: "/images/tig-training.jpg",
+ featured: true
+ },
+ {
+ title: "Welding Inspector Certification",
+ slug: "welding-inspector-certification",
+ description: "Comprehensive training for AWS Certified Welding Inspector (CWI) certification. Learn inspection techniques, codes, and standards.",
+ level: "advanced",
+ duration: "120 hours (3 weeks)",
+ price: 2499.99,
+ curriculum: [
+ {
+ module: "Welding Codes and Standards",
+ topics: ["AWS D1.1 Structural", "API 1104 Pipeline", "ASME Section IX", "International standards"]
+ },
+ {
+ module: "Inspection Techniques",
+ topics: ["Visual inspection", "NDT methods", "Documentation", "Quality assurance"]
+ },
+ {
+ module: "Metallurgy and Materials",
+ topics: ["Steel metallurgy", "Heat treatment", "Material properties", "Failure analysis"]
+ }
+ ],
+ prerequisites: ["5+ years welding experience", "High school diploma", "Vision test"],
+ certification: "AWS Certified Welding Inspector (CWI)",
+ instructor: {
+ name: "Robert Thompson",
+ bio: "Senior CWI with 20+ years in aerospace and nuclear industries",
+ image: "/images/instructor-robert.jpg"
+ },
+ schedule: [
+ {
+ startDate: new Date('2024-03-01'),
+ endDate: new Date('2024-03-22'),
+ location: "Certification Center",
+ maxStudents: 20,
+ enrolledStudents: 15
+ }
+ ],
+ image: "/images/inspector-training.jpg",
+ featured: false
+ }
+ ]
+
+ const createdCourses = await TrainingCourse.insertMany(trainingCourses)
+ console.log(`Seeded ${createdCourses.length} training courses`)
+
+ // Seed Job Postings
+ const jobPostings = [
+ {
+ title: "Senior Welding Engineer",
+ department: "Engineering",
+ location: "Houston, TX",
+ type: "full-time",
+ experience: "5+ years",
+ salary: {
+ min: 85000,
+ max: 120000,
+ currency: "USD"
+ },
+ description: "Lead welding engineering projects for oil & gas industry clients. Develop welding procedures, oversee quality control, and manage welding operations.",
+ responsibilities: [
+ "Develop and qualify welding procedures (WPS/PQR)",
+ "Oversee welding operations and quality control",
+ "Train and mentor junior welding staff",
+ "Interface with clients on technical requirements",
+ "Conduct failure analysis and troubleshooting"
+ ],
+ requirements: [
+ "Bachelor's degree in Welding Engineering or related field",
+ "AWS Certified Welding Inspector (CWI) required",
+ "5+ years of industrial welding experience",
+ "Experience with ASME and API codes",
+ "Strong leadership and communication skills"
+ ],
+ benefits: [
+ "Competitive salary with performance bonuses",
+ "Comprehensive health, dental, and vision insurance",
+ "401(k) with company matching",
+ "Professional development opportunities",
+ "Flexible work arrangements"
+ ],
+ skills: ["Welding Engineering", "AWS Codes", "ASME", "API", "Quality Control", "Leadership"],
+ featured: true,
+ applicationDeadline: new Date('2024-03-15')
+ },
+ {
+ title: "Certified Welder - Structural Steel",
+ department: "Production",
+ location: "Denver, CO",
+ type: "full-time",
+ experience: "3-5 years",
+ salary: {
+ min: 55000,
+ max: 75000,
+ currency: "USD"
+ },
+ description: "Perform structural steel welding for construction projects. Must be certified in SMAW, GMAW, and FCAW processes.",
+ responsibilities: [
+ "Perform structural steel welding per AWS D1.1",
+ "Read and interpret welding symbols and blueprints",
+ "Maintain welding equipment and tools",
+ "Follow safety procedures and quality standards",
+ "Complete daily production reports"
+ ],
+ requirements: [
+ "AWS D1.1 Structural Welding Certification",
+ "3+ years of structural welding experience",
+ "Ability to pass welding tests in all positions",
+ "Basic blueprint reading skills",
+ "Physical ability to work in various positions"
+ ],
+ benefits: [
+ "Competitive hourly wages",
+ "Health insurance",
+ "Paid time off",
+ "Safety bonus program",
+ "Tool allowance"
+ ],
+ skills: ["SMAW", "GMAW", "FCAW", "Structural Welding", "Blueprint Reading", "AWS D1.1"],
+ featured: false,
+ applicationDeadline: new Date('2024-02-28')
+ },
+ {
+ title: "Welding Instructor",
+ department: "Training",
+ location: "Phoenix, AZ",
+ type: "full-time",
+ experience: "5+ years",
+ salary: {
+ min: 65000,
+ max: 85000,
+ currency: "USD"
+ },
+ description: "Teach welding courses to students of all skill levels. Develop curriculum and maintain training equipment.",
+ responsibilities: [
+ "Conduct welding classes for various skill levels",
+ "Develop and update training curriculum",
+ "Maintain training equipment and workshop",
+ "Assess student progress and provide feedback",
+ "Prepare students for certification exams"
+ ],
+ requirements: [
+ "AWS Certified Welding Educator (CWE) preferred",
+ "5+ years of welding experience",
+ "Teaching or training experience",
+ "Excellent communication skills",
+ "Patience and ability to work with diverse learners"
+ ],
+ benefits: [
+ "Competitive salary",
+ "Summer break schedule",
+ "Professional development funding",
+ "Health and retirement benefits",
+ "Job security in growing field"
+ ],
+ skills: ["Teaching", "Curriculum Development", "AWS Certification", "Multiple Welding Processes", "Student Assessment"],
+ featured: true,
+ applicationDeadline: new Date('2024-04-01')
+ }
+ ]
+
+ const createdJobs = await JobPosting.insertMany(jobPostings)
+ console.log(`Seeded ${createdJobs.length} job postings`)
+
+ console.log('Database seeding completed successfully!')
+ console.log('\nSeeded data summary:')
+ console.log(`- ${createdProducts.length} products`)
+ console.log(`- ${createdIndustries.length} industries`)
+ console.log(`- ${createdCourses.length} training courses`)
+ console.log(`- ${createdJobs.length} job postings`)
+
+ } catch (error) {
+ console.error('Error seeding database:', error)
+ } finally {
+ await mongoose.connection.close()
+ console.log('Database connection closed')
+ }
+}
+
+seedData()
\ No newline at end of file