Learn how to create an online test booking system with Lovable. Our step-by-step guide helps you streamline scheduling and boost efficiency.
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Creating a New Lovable Project
Configuring Project Dependencies
lovable.config.json
.lovable.config.json
to include the booking and database libraries:
{
"dependencies": {
"lovable-booking": "latest",
"lovable-db": "latest"
}
}
Setting Up the Server and Routing
server.lov
. This file will contain your backend code.server.lov
to import dependencies, set up the server, and define a booking route:
// Import the built-in modules from Lovable
import Booking from "lovable-booking";
import Database from "lovable-db";
// Initialize the database connection
let db = new Database("OnlineTestDB");
// Create an instance of the booking manager
let bookingManager = new Booking(db);
// Define a route for creating a new test booking
lovable.route("POST", "/book-test", (req, res) => {
// Extract the booking details from the request body
let { fullName, email, testDate } = req.body;
// Validate the input
if (!fullName || !email || !testDate) {
res.status(400).send({ error: "Missing required booking information." });
return;
}
// Save booking to the database
bookingManager.createBooking({ fullName, email, testDate })
.then(result => {
res.status(200).send({ message: "Booking confirmed", bookingId: result.id });
})
.catch(error => {
res.status(500).send({ error: "Booking failed: " + error.message });
});
});
// Start the server on Lovable's default port
lovable.startServer();
Creating the Booking Form (Frontend)
bookingForm.html
for the booking form page.bookingForm.html
to define the form structure:
Online Test Booking
Book Your Test
Adding Client-Side Logic
booking.js
to handle the form submission.booking.js
to capture form data and send it to the server:
document.getElementById('bookingForm').addEventListener('submit', function(event) {
event.preventDefault(); // Prevent the default form submission
// Gather form data
let fullName = document.getElementById('fullName').value;
let email = document.getElementById('email').value;
let testDate = document.getElementById('testDate').value;
// Create the booking data object
let bookingData = { fullName, email, testDate };
// Send a POST request to the server endpoint using Lovable's HTTP client
lovable.http.post("/book-test", bookingData)
.then(response => {
alert("Booking confirmed. Your Booking ID: " + response.bookingId);
})
.catch(error => {
alert("Error during booking: " + error.error);
});
});
Styling the Booking Form
styles.css
to improve the form's appearance.styles.css
:
body {
font-family: Arial, sans-serif;
background-color: #f9f9f9;
padding: 20px;
}
h1 {
color: #333;
}
form {
background-color: #fff;
padding: 25px;
border-radius: 5px;
box-shadow: 0px 0px 10px #ccc;
max-width: 400px;
margin: auto;
}
input[type="text"],
input[type="email"],
input[type="date"] {
width: 100%;
padding: 10px;
margin: 8px 0;
border: 1px solid #ccc;
border-radius: 3px;
}
button {
background-color: #5cb85c;
color: white;
padding: 10px 15px;
border: none;
border-radius: 3px;
cursor: pointer;
}
button:hover {
background-color: #4cae4c;
}
Connecting All Components in Lovable
server.lov
file as the main backend file.bookingForm.html
as the landing (home) page of your project.bookingForm.html
, booking.js
, styles.css
, and server.lov
) are saved in the correct directory (typically the project root or designated folders as outlined in your Lovable documentation).
Testing Your Booking Application
server.lov
.bookingForm.html
page.
Deploying and Sharing Your Application
const express = require('express');
const mongoose = require('mongoose');
const app = express();
app.use(express.json());
mongoose.connect('mongodb://localhost:27017/lovableTestBooking', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const testBookingSchema = new mongoose.Schema({
userId: { type: mongoose.Schema.Types.ObjectId, required: true },
testId: { type: mongoose.Schema.Types.ObjectId, required: true },
bookingDate: { type: Date, required: true },
status: { type: String, default: 'pending' },
additionalInfo: { type: Object },
createdAt: { type: Date, default: Date.now }
});
const TestBooking = mongoose.model('TestBooking', testBookingSchema);
app.post('/api/bookTest', async (req, res) => {
const { userId, testId, bookingDate, additionalInfo } = req.body;
// Check if desired slot is already booked
const existingBooking = await TestBooking.findOne({ testId, bookingDate });
if (existingBooking) {
return res.status(409).json({ message: 'Test slot already booked' });
}
// Create and save new test booking
const newBooking = new TestBooking({ userId, testId, bookingDate, additionalInfo });
try {
await newBooking.save();
res.status(201).json({ message: 'Booking successful', booking: newBooking });
} catch (error) {
res.status(500).json({ message: 'Error booking test', error });
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json());
app.post('/api/external/bookTest', async (req, res) => {
const { bookingId, userId, testId, scheduleTime } = req.body;
try {
const apiPayload = {
bookingReference: bookingId,
user: userId,
test: testId,
time: scheduleTime
};
const externalResponse = await axios.post(
'https://api.lovable-external.com/validateBooking',
apiPayload,
{ headers: { 'Authorization': `Bearer ${process.env.EXTERNAL_API_KEY}` } }
);
if (externalResponse.data.status === 'approved') {
res.status(200).json({ message: 'Test booking approved', details: externalResponse.data });
} else {
res.status(400).json({ message: 'Test booking rejected', reason: externalResponse.data.reason });
}
} catch (error) {
res.status(500).json({ message: 'Error processing booking with external service', error: error.message });
}
});
const PORT = process.env.PORT || 4000;
app.listen(PORT, () => console.log(`Server listening on port ${PORT}`));
const express = require('express');
const mongoose = require('mongoose');
const app = express();
app.use(express.json());
mongoose.connect('mongodb://localhost:27017/lovableTestBooking', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const testBookingSchema = new mongoose.Schema({
userId: { type: mongoose.Schema.Types.ObjectId, required: true },
testId: { type: mongoose.Schema.Types.ObjectId, required: true },
bookingDate: { type: Date, required: true },
status: { type: String, enum: ['pending', 'approved', 'rescheduled', 'cancelled'], default: 'pending' },
createdAt: { type: Date, default: Date.now }
});
const auditLogSchema = new mongoose.Schema({
bookingId: { type: mongoose.Schema.Types.ObjectId, required: true },
action: { type: String, required: true },
timestamp: { type: Date, default: Date.now },
details: { type: Object }
});
const TestBooking = mongoose.model('TestBooking', testBookingSchema);
const AuditLog = mongoose.model('AuditLog', auditLogSchema);
app.post('/api/rescheduleBooking', async (req, res) => {
const session = await mongoose.startSession();
session.startTransaction();
try {
const { bookingId, newBookingDate } = req.body;
const booking = await TestBooking.findById(bookingId).session(session);
if (!booking) {
await session.abortTransaction();
return res.status(404).json({ message: 'Booking not found' });
}
const conflictBooking = await TestBooking.findOne({
testId: booking.testId,
bookingDate: newBookingDate
}).session(session);
if (conflictBooking) {
await session.abortTransaction();
return res.status(409).json({ message: 'New slot already booked' });
}
const originalDate = booking.bookingDate;
booking.bookingDate = newBookingDate;
booking.status = 'rescheduled';
await booking.save({ session });
const audit = new AuditLog({
bookingId: booking.\_id,
action: 'Rescheduled',
details: { oldDate: originalDate, newDate: newBookingDate }
});
await audit.save({ session });
await session.commitTransaction();
res.status(200).json({ message: 'Booking rescheduled successfully', booking });
} catch (error) {
await session.abortTransaction();
res.status(500).json({ message: 'Error rescheduling booking', error: error.message });
} finally {
session.endSession();
}
});
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Introduction to Building an Online Test Booking with AI Code Generators
Building an online test booking system enhanced by AI code generators involves integrating a robust backend, a user-friendly frontend, and AI-based components to automate code generation and testing tasks. This guide provides non-technical users with a step-by-step walkthrough to understand the process and adopt best practices.
Prerequisites
Defining the Feature Requirements
Planning the System Architecture
Integrating AI Code Generators
fetch('https://api.aicodeservice.com/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
prompt: 'Generate a booking form for a test appointment.',
language: 'HTML'
})
})
.then(response => response.json())
.then(data => {
console.log('Generated Code:', data.generated\_code);
})
.catch(error => {
console.error('Error:', error);
});
Designing the Frontend User Interface
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test Booking</title>
</head>
<body>
<h1>Book Your Test</h1>
<form id="bookingForm">
<label for="testType">Select Test:</label>
<select id="testType" name="testType">
<option value="math">Math</option>
<option value="science">Science</option>
</select>
<br>
<label for="date">Select Date:</label>
<input type="date" id="date" name="date">
<br>
<button type="submit">Book Now</button>
</form>
</body>
</html>
Implementing the Backend System
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.post('/book-test', (req, res) => {
const { testType, date } = req.body;
// Process the booking logic here
res.json({ message: 'Test booked successfully', testType, date });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Ensuring Security and Data Privacy
Integrating Payment Gateways and Notifications
Testing and Quality Assurance
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.