Snaplocal / server /src /index.js
Kuruva Laxmi
Expand dummy photographer seed data to 7 profiles
d71a01e
Raw
History Blame Contribute Delete
11.4 kB
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const dotenv = require('dotenv');
const http = require('http');
const { Server } = require('socket.io');
dotenv.config();
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: process.env.ALLOWED_ORIGINS ? process.env.ALLOWED_ORIGINS.split(',') : "*",
methods: ["GET", "POST", "PUT", "DELETE"],
credentials: true
}
});
// Socket.io Logic
const Message = require('./models/Message');
const Notification = require('./models/Notification');
io.on('connection', (socket) => {
console.log('User connected:', socket.id);
socket.on('join', (userId) => {
socket.join(userId);
console.log(`User ${userId} joined their room`);
});
socket.on('sendMessage', async (data) => {
try {
const { sender, receiver, content, bookingId } = data;
const message = await Message.create({ sender, receiver, content, bookingId });
// Emit to receiver
io.to(receiver).emit('receiveMessage', message);
// Emit to sender for confirmation/sync
io.to(sender).emit('receiveMessage', message);
} catch (err) {
console.error('Socket message error:', err);
}
});
socket.on('instantBookingRequest', async (data) => {
try {
const { customerId, photographerId, bookingDetails } = data;
// Emit to specific photographer
io.to(photographerId).emit('receiveBookingRequest', {
customerId,
bookingDetails,
socketId: socket.id
});
} catch (err) {
console.error('Instant booking error:', err);
}
});
socket.on('bookingResponse', (data) => {
const { customerSocketId, accepted, bookingId } = data;
io.to(customerSocketId).emit('bookingStatusUpdate', { accepted, bookingId });
});
socket.on('disconnect', () => {
console.log('User disconnected');
});
});
// Middleware to inject io into requests if needed
app.use((req, res, next) => {
req.io = io;
next();
});
// Middleware
app.use(cors({
origin: process.env.ALLOWED_ORIGINS ? process.env.ALLOWED_ORIGINS.split(',') : "*",
credentials: true
}));
app.use(express.json());
// Routes
const authRoutes = require('./routes/authRoutes');
const bookingRoutes = require('./routes/bookingRoutes');
const userRoutes = require('./routes/userRoutes');
const reviewRoutes = require('./routes/reviewRoutes');
const chatRoutes = require('./routes/chatRoutes');
const notificationRoutes = require('./routes/notificationRoutes');
const recommendationRoutes = require('./routes/recommendationRoutes');
const packageRoutes = require('./routes/packageRoutes');
const verificationRoutes = require('./routes/verificationRoutes');
const deliveryRoutes = require('./routes/deliveryRoutes');
const invoiceRoutes = require('./routes/invoiceRoutes');
const reportRoutes = require('./routes/reportRoutes');
const loyaltyRoutes = require('./routes/loyaltyRoutes');
const tripPlanRoutes = require('./routes/tripPlanRoutes');
const dealRoutes = require('./routes/dealRoutes');
app.use('/api/auth', authRoutes);
app.use('/api/bookings', bookingRoutes);
app.use('/api/users', userRoutes);
app.use('/api/reviews', reviewRoutes);
app.use('/api/chat', chatRoutes);
app.use('/api/notifications', notificationRoutes);
app.use('/api/recommendations', recommendationRoutes);
app.use('/api/packages', packageRoutes);
app.use('/api/verification', verificationRoutes);
app.use('/api/delivery', deliveryRoutes);
app.use('/api/invoices', invoiceRoutes);
app.use('/api/reports', reportRoutes);
app.use('/api/loyalty', loyaltyRoutes);
app.use('/api/trips', tripPlanRoutes);
app.use('/api/deals', dealRoutes);
const User = require('./models/User');
const seedDatabase = async () => {
try {
const userCount = await User.countDocuments();
if (userCount === 0) {
console.log('Database is empty. Seeding dummy photographers...');
const dummyPhotographers = [
{
firstName: 'Aisha',
lastName: 'Sharma',
email: 'aisha@example.com',
password: 'password123',
role: 'photographer',
roles: ['photographer'],
specialty: 'Portrait',
address: 'Hyderabad, Telangana',
price: 1500,
experience: 5,
rating: 4.9,
isVerified: true,
bio: 'Professional portrait photographer with 5 years of experience capturing moments in Hyderabad.',
profilePicture: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?auto=format&fit=crop&w=400&h=400',
portfolio: [
{ url: 'https://images.unsplash.com/photo-1511895426328-dc8714191300?auto=format&fit=crop&w=800&h=800' },
{ url: 'https://images.unsplash.com/photo-1520854221256-17451cc331bf?auto=format&fit=crop&w=800&h=800' }
]
},
{
firstName: 'Vikram',
lastName: 'Singh',
email: 'vikram@example.com',
password: 'password123',
role: 'photographer',
roles: ['photographer'],
specialty: 'Wedding',
address: 'Mumbai, Maharashtra',
price: 3000,
experience: 8,
rating: 4.7,
isVerified: true,
bio: 'Specializing in cinematic wedding photography and candid moments.',
profilePicture: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?auto=format&fit=crop&w=400&h=400',
portfolio: [
{ url: 'https://images.unsplash.com/photo-1511285560929-80b456fea0bc?auto=format&fit=crop&w=800&h=800' }
]
},
{
firstName: 'Priya',
lastName: 'Patel',
email: 'priya@example.com',
password: 'password123',
role: 'photographer',
roles: ['photographer'],
specialty: 'Event',
address: 'Bangalore, Karnataka',
price: 2000,
experience: 3,
rating: 4.8,
isVerified: false,
bio: 'Energetic event photographer covering corporate events and private parties.',
profilePicture: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&w=400&h=400',
portfolio: [
{ url: 'https://images.unsplash.com/photo-1505236858219-8359eb29e329?auto=format&fit=crop&w=800&h=800' }
]
},
{
firstName: 'Rohan',
lastName: 'Verma',
email: 'rohan@example.com',
password: 'password123',
role: 'photographer',
roles: ['photographer'],
specialty: 'Real Estate',
address: 'Delhi, NCR',
price: 2500,
experience: 6,
rating: 4.9,
isVerified: true,
bio: 'Expert architectural and real estate photographer. I bring homes to life through dynamic lighting.',
profilePicture: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=400&h=400',
portfolio: [
{ url: 'https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?auto=format&fit=crop&w=800&h=800' },
{ url: 'https://images.unsplash.com/photo-1600607687931-57dce8bb084b?auto=format&fit=crop&w=800&h=800' }
]
},
{
firstName: 'Neha',
lastName: 'Gupta',
email: 'neha@example.com',
password: 'password123',
role: 'photographer',
roles: ['photographer'],
specialty: 'Fashion',
address: 'Hyderabad, Telangana',
price: 4000,
experience: 10,
rating: 4.6,
isVerified: true,
bio: 'High-end fashion and editorial photography for bold personalities.',
profilePicture: 'https://images.unsplash.com/photo-1517841905240-472988babdf9?auto=format&fit=crop&w=400&h=400',
portfolio: [
{ url: 'https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?auto=format&fit=crop&w=800&h=800' },
{ url: 'https://images.unsplash.com/photo-1483985988355-763728e1935b?auto=format&fit=crop&w=800&h=800' }
]
},
{
firstName: 'Arjun',
lastName: 'Reddy',
email: 'arjun@example.com',
password: 'password123',
role: 'photographer',
roles: ['photographer'],
specialty: 'Automotive',
address: 'Chennai, Tamil Nadu',
price: 1800,
experience: 4,
rating: 4.8,
isVerified: false,
bio: 'Capturing speed and aesthetics. I shoot cars, bikes, and motorsport events.',
profilePicture: 'https://images.unsplash.com/photo-1492562080023-ab3db95bfbce?auto=format&fit=crop&w=400&h=400',
portfolio: [
{ url: 'https://images.unsplash.com/photo-1494976388531-d1058494cdd8?auto=format&fit=crop&w=800&h=800' }
]
},
{
firstName: 'Meera',
lastName: 'Krishna',
email: 'meera@example.com',
password: 'password123',
role: 'photographer',
roles: ['photographer'],
specialty: 'Food',
address: 'Pune, Maharashtra',
price: 1200,
experience: 2,
rating: 5.0,
isVerified: true,
bio: 'Food stylist and photographer for cafes, restaurants, and cloud kitchens.',
profilePicture: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&w=400&h=400',
portfolio: [
{ url: 'https://images.unsplash.com/photo-1504674900247-0877df9cc836?auto=format&fit=crop&w=800&h=800' },
{ url: 'https://images.unsplash.com/photo-1414235077428-338989a2e8c0?auto=format&fit=crop&w=800&h=800' }
]
}
];
for (const pg of dummyPhotographers) {
const newUser = new User(pg);
await newUser.save();
}
console.log('Successfully seeded 7 dummy photographers.');
}
} catch (err) {
console.error('Failed to seed database:', err);
}
};
const connectDB = async () => {
try {
let uri = process.env.MONGODB_URI;
let isMemory = false;
if (!uri || uri === "undefined") {
console.log('No MONGODB_URI found. Starting In-Memory MongoDB Server for demo purposes...');
const { MongoMemoryServer } = require('mongodb-memory-server');
const mongoServer = await MongoMemoryServer.create();
uri = mongoServer.getUri();
isMemory = true;
console.log('In-Memory MongoDB started successfully!');
}
await mongoose.connect(uri);
console.log('MongoDB connected successfully');
if (isMemory) {
await seedDatabase();
}
} catch (err) {
console.error('MongoDB connection error:', err);
}
};
connectDB();
// Serve Static Frontend (for Full-Stack Deployment)
const path = require('path');
const clientDistPath = path.join(__dirname, '../../client/dist');
app.use(express.static(clientDistPath));
app.get(/(.*)/, (req, res, next) => {
if (req.path.startsWith('/api')) return next();
res.sendFile(path.join(clientDistPath, 'index.html'), (err) => {
if (err) res.send('SnapLocal Pro API is running with Real-time support... (Frontend not built yet)');
});
});
const PORT = process.env.PORT || 5000;
server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});