Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions Backend/Controllers/ambulanceController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import AmbulanceBooking from "../models/AmbulanceBookingSchema.js";
import User from "../models/UserSchema.js";
import { sendEmail } from "../utils/sendEmail.js";

export const bookAmbulance = async (req, res) => {
const { pickupAddress, destination } = req.body;
const patientId = req.user.id;

try {
// Check for active bookings (pending or running)
const activeBooking = await AmbulanceBooking.findOne({
patientId,
status: { $in: ["pending", "running"] },
});

if (activeBooking) {
return res.status(400).json({
success: false,
message: "You already have an active ambulance booking. Please wait until it’s completed.",
});
}

const booking = new AmbulanceBooking({
patientId,
pickupAddress,
destination,
});
await booking.save();

// Socket.io: Notify patient
const io = req.app.get('io');
io.to(patientId).emit('bookingUpdate', { bookingId: booking._id, status: 'pending' });

// Notify drivers via email and Socket.io
const drivers = await User.find({ role: "driver" });
const driverEmails = drivers.map((driver) => driver.email);
const subject = "New Ambulance Booking Request";
const message = `A new ambulance booking request has been made.\nPickup: ${pickupAddress}\nDestination: ${destination}\nBooking ID: ${booking._id}`;

await Promise.all(
driverEmails.map((email) => sendEmail(email, subject, { text: message }))
);

drivers.forEach(driver => {
io.to(driver._id.toString()).emit('newBooking', booking);
});

res.status(200).json({ success: true, message: "Ambulance booked, drivers notified", data: booking });
} catch (err) {
console.error("Error booking ambulance:", err);
res.status(500).json({ success: false, message: "Failed to book ambulance" });
}
};

// Rest of the controller remains unchanged
export const acceptBooking = async (req, res) => {
const bookingId = req.params.id;
const driverId = req.user.id;

try {
const booking = await AmbulanceBooking.findById(bookingId);
if (!booking) {
return res.status(404).json({ success: false, message: "Booking not found" });
}
if (booking.status !== "pending") {
return res.status(400).json({ success: false, message: "Booking already assigned or completed" });
}

booking.driverId = driverId;
booking.status = "running";
await booking.save();

const io = req.app.get('io');
io.to(booking.patientId.toString()).emit('bookingUpdate', { bookingId, status: 'running' });
io.to(driverId).emit('bookingUpdate', { bookingId, status: 'running' });

res.status(200).json({ success: true, message: "Booking accepted", data: booking });
} catch (err) {
console.error("Error accepting booking:", err);
res.status(500).json({ success: false, message: "Failed to accept booking" });
}
};

export const updateBookingStatus = async (req, res) => {
const bookingId = req.params.id;
const { status } = req.body;
const driverId = req.user.id;

try {
if (!["pending", "running", "completed"].includes(status)) {
return res.status(400).json({ success: false, message: "Invalid status value" });
}

const booking = await AmbulanceBooking.findById(bookingId);
if (!booking || booking.driverId.toString() !== driverId) {
return res.status(403).json({ success: false, message: "Unauthorized or booking not found" });
}

booking.status = status;
const updatedBooking = await booking.save();

const io = req.app.get('io');
io.to(booking.patientId.toString()).emit('bookingUpdate', { bookingId, status });
io.to(driverId).emit('bookingUpdate', { bookingId, status });

res.status(200).json({ success: true, message: "Status updated", data: updatedBooking });
} catch (err) {
console.error("Error updating booking status:", err);
res.status(500).json({ success: false, message: "Failed to update status" });
}
};

export const getDriverDashboard = async (req, res) => {
const driverId = req.user.id;

try {
const newRequests = await AmbulanceBooking.find({ status: "pending" });
const driverBookings = await AmbulanceBooking.find({ driverId });
res.status(200).json({
success: true,
message: "Dashboard data retrieved",
data: { newRequests, myBookings: driverBookings },
});
} catch (err) {
console.error("Error fetching driver dashboard:", err);
res.status(500).json({ success: false, message: "Failed to fetch dashboard data" });
}
};

export const getBookingStatus = async (req, res) => {
const bookingId = req.params.id;
const userId = req.user.id;

try {
const booking = await AmbulanceBooking.findById(bookingId);
if (!booking || booking.patientId.toString() !== userId) {
return res.status(403).json({ success: false, message: "Unauthorized or booking not found" });
}
res.status(200).json({ success: true, message: "Booking status retrieved", data: booking });
} catch (err) {
console.error("Error fetching booking status:", err);
res.status(500).json({ success: false, message: "Failed to fetch booking status" });
}
};
205 changes: 102 additions & 103 deletions Backend/Controllers/authController.js
Original file line number Diff line number Diff line change
@@ -1,117 +1,116 @@
import jwt from 'jsonwebtoken'
import bcrypt from 'bcryptjs'
import User from '../models/UserSchema.js'
import Doctor from "../models/DoctorSchema.js"
import dotenv from 'dotenv'
import jwt from "jsonwebtoken";
import bcrypt from "bcryptjs";
import User from "../models/UserSchema.js";
import Doctor from "../models/DoctorSchema.js";
import dotenv from "dotenv";

dotenv.config();

const generateToken = (user) => {
return jwt.sign(
{ id: user._id, role: user.role },
process.env.JWT_SECRET_KEY,
{ expiresIn: "15d" }
);
};

dotenv.config()
export const register = async (req, res) => {
const { email, password, name, role, photo, gender, licenseNumber, ambulanceNumber } = req.body;
try {
let user = null;

if (role === "patient" || role === "driver") {
user = await User.findOne({ email });
} else if (role === "doctor") {
user = await Doctor.findOne({ email });
}

const generateToken = user => {
return jwt.sign(
{id: user._id, role:user.role},
process.env.JWT_SECRET_KEY,
{
expiresIn:'15d',
if (user) {
return res.status(400).json({ message: "User already exists" });
}
)
}

export const register = async (req,res) => {
const {email, password, name, role, photo, gender} = req.body;
try {

let user = null
if(role === 'patient'){
user=await User.findOne({email})
}
else if(role==='doctor'){
user=await Doctor.findOne({email})
}

// check if user exist
if(user){
return res.status(400).json({message:'User already exist'})
}

// #hash password
const salt = await bcrypt.genSalt(10)
const hashPassword = await bcrypt.hash(password,salt)

if(role==='patient'){
user = new User ({
name,
email,
password:hashPassword,
photo,
gender,
role
})
}

if(role==='doctor'){
user = new Doctor ({
name,
email,
password:hashPassword,
photo,
gender,
role
})
}
await user.save()
res.status(200).json({success:true, message:"User successfully created"})

} catch(err) {
res.status(500).json({success:true, message:"Internal server error"})
};
};

const salt = await bcrypt.genSalt(10);
const hashPassword = await bcrypt.hash(password, salt);

if (role === "patient") {
user = new User({
name,
email,
password: hashPassword,
photo,
gender,
role,
});
} else if (role === "driver") {
if (!licenseNumber || !ambulanceNumber) {
return res.status(400).json({ success: false, message: "licenseNumber and ambulanceNumber are required for drivers" });
}
console.log("Registering driver with:", { email, name, licenseNumber, ambulanceNumber });
user = new User({
name,
email,
password: hashPassword,
photo,
gender,
role,
licenseNumber,
ambulanceNumber,
});
} else if (role === "doctor") {
user = new Doctor({
name,
email,
password: hashPassword,
photo,
gender,
role,
});
}

await user.save();
res.status(200).json({ success: true, message: "User successfully created" });
} catch (err) {
console.error("Error in register:", err);
if (err.name === "ValidationError") {
return res.status(400).json({ success: false, message: "Validation error", errors: err.errors });
}
res.status(500).json({ success: false, message: "Internal server error", error: err.message });
}
};

export const login = async (req, res) => {
const { email } = req.body;

try {
let user = null;
const { email } = req.body;

const patient = await User.findOne({ email });
const doctor = await Doctor.findOne({ email });
try {
let user = null;

if (patient) {
user = patient;
}
if (doctor) {
user = doctor;
}
const patient = await User.findOne({ email });
const doctor = await Doctor.findOne({ email });

// Check if user exists or not
if (!user) {
return res.status(404).json({ message: "User not found" });
}
if (patient) user = patient;
if (doctor) user = doctor;

const isPasswordMatch = await bcrypt.compare(req.body.password, user.password);

if (!isPasswordMatch) {
return res.status(400).json({ status: false, message: "Invalid credentials" });
}

// Get token
const token = generateToken(user);

const { password, role, appointments, ...rest } = user._doc;

// ✅ Send userId along with response
res.status(200).json({
status: true,
message: "Successfully logged in",
token,
userId: user._id, // <-- Add this
data: { ...rest },
role,
});
if (!user) {
return res.status(404).json({ message: "User not found" });
}

} catch (err) {
res.status(500).json({ status: false, message: "Failed login" });
const isPasswordMatch = await bcrypt.compare(req.body.password, user.password);
if (!isPasswordMatch) {
return res.status(400).json({ status: false, message: "Invalid credentials" });
}
};

const token = generateToken(user);
const { password, role, appointments, ...rest } = user._doc;

res.status(200).json({
status: true,
message: "Successfully logged in",
token,
userId: user._id,
data: { ...rest },
role,
});
} catch (err) {
res.status(500).json({ status: false, message: "Failed login" });
}
};
Loading
Loading