import "dotenv/config"; import express from "express"; import mysql from "mysql2/promise"; // Create a connection pool to MySQL const pool = mysql.createPool({ host: process.env.DB_HOST || "localhost", user: process.env.DB_USER || "root", password: process.env.DB_PASSWORD, database: process.env.DB_NAME || "roadrentals", waitForConnections: true, connectionLimit: 10, queueLimit: 0 }); const app = express(); app.use(express.json()); const checkToken = (req, res, next) => { console.log("Welcome"); next(); }; app.use(checkToken); app.get("/", (req, res) => { res.json({ status: 1, message: "Home Page API" }); }); app.get("/api/news", (req, res) => { res.json({ status: 1, message: "News API" }); }); // Database Connected Endpoint app.post("/api/auth/register", async (req, res) => { try { const { name, email, mobile_number, password } = req.body; if (!name || !email || !mobile_number || !password) { return res.status(400).json({ detail: "Missing required fields" }); } // Search the MySQL Database const [users] = await pool.execute("SELECT * FROM User WHERE email = ?", [email]); const existingUser = users[0]; if (existingUser) { return res.status(409).json({ detail: "Email already registered" }); } // Insert new user row into MySQL table const [result] = await pool.execute( "INSERT INTO User (name, email, mobile_number, password) VALUES (?, ?, ?, ?)", [name, email, mobile_number, password] ); const newUser = { id: result.insertId, name, email, mobile_number }; return res.status(201).json({ status: 1, message: "User registered successfully", user: newUser }); } catch (error) { console.error("Database Error:", error); return res.status(500).json({ detail: "Internal Server Error" }); } }); // Create a New Booking app.post("/api/bookings", async (req, res) => { try { const { tripType, pickupLocation, dropLocation, pickupDateTime, returnDateTime, packageType, carName, totalAmount } = req.body; if (!tripType || !pickupLocation || !pickupDateTime) { return res.status(400).json({ detail: "Missing required booking details" }); } const [result] = await pool.execute( `INSERT INTO Bookings (trip_type, pickup_location, drop_location, pickup_datetime, return_datetime, package_type, car_name, total_amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [ tripType, pickupLocation, dropLocation || null, new Date(pickupDateTime), returnDateTime ? new Date(returnDateTime) : null, packageType || null, carName || null, totalAmount || null ] ); return res.status(201).json({ status: 1, message: "Booking requested successfully!", bookingId: result.insertId }); } catch (error) { console.error("Booking Error:", error); return res.status(500).json({ detail: "Failed to create booking" }); } }); // Pricing Engine & Car Data const VEHICLES = [ // LUXURY TIER { id: 1, name: "Audi A6 Premium", type: "LUXURY", seats: "4+1", luggage: "2 Bags", image: "audi_a6", baseFarePerDay: 12000, driverAllowancePerDay: 600, extraKmRate: 45, includedKmPerDay: 250, badge: "Executive", features: ["Leather Interior", "Dual Climate", "Premium Audio", "Sunroof"] }, { id: 2, name: "BMW 7 Series", type: "LUXURY", seats: "4+1", luggage: "3 Bags", image: "bmw_7_series", baseFarePerDay: 25000, driverAllowancePerDay: 800, extraKmRate: 85, includedKmPerDay: 200, badge: "VVIP Choice", features: ["Rear-seat Entertainment", "Massage Seats", "Quiet Cabin", "Chauffeur Driven"] }, { id: 3, name: "Mercedes S-Class", type: "LUXURY", seats: "4+1", luggage: "2 Bags", image: "mercedes_s_class", baseFarePerDay: 28000, driverAllowancePerDay: 800, extraKmRate: 90, includedKmPerDay: 200, badge: "Ultimate Luxury", features: ["Ambient Lighting", "Burmester Sound", "Premium Chauffeur"] }, // SUV/MUV TIER { id: 4, name: "Toyota Fortuner 4x4", type: "SUV", seats: "6+1", luggage: "4 Bags", image: "fortuner", baseFarePerDay: 6500, driverAllowancePerDay: 500, extraKmRate: 25, includedKmPerDay: 300, badge: "Advanture King", features: ["Off-road capable", "Powerful AC", "Spacious", "Rugged Built"] }, { id: 5, name: "Innova Crysta", type: "MUV", seats: "7+1", luggage: "3 Bags", image: "innova_crysta", baseFarePerDay: 4500, driverAllowancePerDay: 400, extraKmRate: 18, includedKmPerDay: 300, badge: "Best Seller", features: ["Clean Interiors", "Captain Seats", "Smooth Ride", "Carrier Available"] }, { id: 6, name: "Toyota Innova", type: "MUV", seats: "7+1", luggage: "2 Bags", image: "innova", baseFarePerDay: 3800, driverAllowancePerDay: 400, extraKmRate: 16, includedKmPerDay: 300, badge: "Value MUV", features: ["Comfortable", "Spacious", "Economical for Family"] }, // SEDAN TIER { id: 7, name: "Toyota Camry", type: "SEDAN", seats: "4+1", luggage: "2 Bags", image: "camry", baseFarePerDay: 4200, driverAllowancePerDay: 400, extraKmRate: 18, includedKmPerDay: 300, badge: "Corporate Elite", features: ["Hybrid Tech", "Quiet Ride", "Executive Space"] }, { id: 8, name: "Toyota Etios", type: "SEDAN", seats: "4+1", luggage: "2 Bags", image: "etios", baseFarePerDay: 2800, driverAllowancePerDay: 400, extraKmRate: 13, includedKmPerDay: 300, badge: "Economic", features: ["Spacious Boot", "Good Legroom", "Standard AC"] }, { id: 9, name: "Swift Dzire", type: "SEDAN", seats: "4+1", luggage: "2 Bags", image: "dzire", baseFarePerDay: 2600, driverAllowancePerDay: 400, extraKmRate: 13, includedKmPerDay: 300, badge: "Economic Choice", features: ["Popular", "Quick Maneuver", "Efficient AC"] }, // GROUP TRAVEL { id: 11, name: "Audi Q7 Luxury SUV", type: "SUV", seats: "6+1", luggage: "4 Bags", image: "audi_q7", baseFarePerDay: 15000, driverAllowancePerDay: 700, extraKmRate: 55, includedKmPerDay: 250, badge: "Luxury SUV", features: ["Quattro 4x4", "Panoramic Sunroof", "Premium Audio", "Heated Seats"] }, { id: 12, name: "BMW 5 Series", type: "LUXURY", seats: "4+1", luggage: "2 Bags", image: "bmw_5_series", baseFarePerDay: 14000, driverAllowancePerDay: 600, extraKmRate: 50, includedKmPerDay: 250, badge: "Business Class", features: ["Dynamic Drive", "Luxury Interiors", "Silent Hybrid", "Touchscreen Control"] }, { id: 13, name: "Mercedes E-Class", type: "LUXURY", seats: "4+1", luggage: "2 Bags", image: "mercedes_e_class", baseFarePerDay: 14500, driverAllowancePerDay: 600, extraKmRate: 52, includedKmPerDay: 250, badge: "Timeless Elegance", features: ["Soft Close Doors", "Ambient Light", "Professional Driver", "WIFI Enabled"] }, { id: 14, name: "Toyota Corolla Altis", type: "SEDAN", seats: "4+1", luggage: "2 Bags", image: "corolla_altis", baseFarePerDay: 3800, driverAllowancePerDay: 400, extraKmRate: 16, includedKmPerDay: 300, badge: "Executive Sedan", features: ["Durable", "Comfortable Suspension", "Clean Air Filter"] } ]; // Lead Capture app.post("/api/leads", async (req, res) => { try { const { name, mobile_number, tripType, pickupLocation, dropLocation } = req.body; if (!name || !mobile_number) return res.status(400).json({ detail: "Name and Mobile are required" }); await pool.execute( `INSERT INTO Leads (name, mobile_number, trip_type, pickup_location, drop_location) VALUES (?, ?, ?, ?, ?)`, [name, mobile_number, tripType || null, pickupLocation || null, dropLocation || null] ); res.status(201).json({ status: 1, message: "Lead captured" }); } catch (error) { console.error("Lead Error:", error); res.status(500).json({ detail: "Failed to capture lead" }); } }); // Centralized Pricing Calculator app.post("/api/pricing/calculate", async (req, res) => { try { const { tripType, pickupDate, returnDate, packageType } = req.body; const start = new Date(pickupDate); const end = returnDate ? new Date(returnDate) : start; const diffTime = Math.abs(end - start); const durationDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) || 1; const results = VEHICLES.map(vehicle => { let totalBaseFare = vehicle.baseFarePerDay * durationDays; let totalDriverAllowance = vehicle.driverAllowancePerDay * durationDays; // Special Case: Local Packages if (tripType === 'local' && packageType) { if (packageType.includes("4Hr")) totalBaseFare = 1500; else if (packageType.includes("8Hr")) totalBaseFare = 2500; else if (packageType.includes("12Hr")) totalBaseFare = 3500; totalDriverAllowance = 0; } // Special Case: Airport Transfers (Flat Rates) if (tripType === 'airport') { if (vehicle.type === 'SEDAN') totalBaseFare = 1200; else if (vehicle.type === 'SUV') totalBaseFare = 2200; else totalBaseFare = 1800; // MUV/Other totalDriverAllowance = 0; } const grandTotal = totalBaseFare + totalDriverAllowance; const advancePayment = Math.round(grandTotal * 0.20); return { ...vehicle, calc: { days: durationDays, baseFare: totalBaseFare, driverAllowance: totalDriverAllowance, totalKmIncluded: vehicle.includedKmPerDay * (tripType === 'airport' ? 0.2 : durationDays), // Approx for airport grandTotal, advancePayment, math: tripType === 'airport' || tripType === 'local' ? `Fixed ${tripType.charAt(0).toUpperCase() + tripType.slice(1)} Rate` : `(₹${vehicle.baseFarePerDay} x ${durationDays} Days) + ₹${totalDriverAllowance} Driver` }, inclusions: ["AC", "Professional Driver", tripType === 'airport' ? "Airport Toll Included" : "First " + (vehicle.includedKmPerDay * durationDays) + " Kms"], exclusions: ["Parking Charges", "Extra Waiting Time", "Inter-state Permits"] }; }); res.json({ status: 1, data: results }); } catch (error) { console.error("Pricing Error:", error); res.status(500).json({ detail: "Failed to calculate pricing" }); } }); const PORT = 8000; app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); });