/how-to-build-lovable

How to build Scheduling app with Lovable?

Learn how to build a scheduling app with Lovable in our step-by-step guide. Simplify bookings, boost productivity, and enhance your user experience.

Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free No-Code consultation

How to build Scheduling app with Lovable?

 
Creating a New Lovable Project
 

  • Log into your Lovable account and navigate to your project dashboard.
  • Click on the "Create New Project" button.
  • Name your project (for example “Scheduling App”) and choose the appropriate template if prompted.

 
Setting Up Your File Structure
 

  • In the Lovable code editor, create the following new files in your project:
    • main.lov – This will be the primary file where your app initializes.
    • scheduler.lov – This file will contain your scheduling logic.
    • lovable.json – Use this file to declare any dependency requirements.

 
Adding Dependencies
 

  • Since Lovable does not support a terminal, you must declare your dependencies directly in the lovable.json file.
  • Add the following snippet to lovable.json to install the scheduling library (for example, using the Python "schedule" module) and any other dependencies you might need:
    • 
      {
        "dependencies": {
          "schedule": "latest"
        }
      }
            
  • This instructs Lovable to include the "schedule" library when your project runs.

 
Writing the Scheduling Logic
 

  • Open the scheduler.lov file and insert the following code snippet. This code sets up a task that prints a message every minute:
    • 
      # scheduler.lov
      # Import the schedule library and time module.
      import schedule
      import time
      
      

      def job():
      # This function contains code for the scheduled task.
      print("Scheduled task executed.")

      Schedule the job to run every 1 minute.

      schedule.every(1).minutes.do(job)

      def run_scheduler():
      # This function continuously checks for scheduled tasks.
      while True:
      schedule.run_pending()
      time.sleep(1)




  • This file defines the job and a function to run the scheduler loop.

 
Integrating the Scheduler with the Main App
 

  • Open the main.lov file and paste the following code. This will import the scheduler module and call its loop, ensuring that your scheduled task runs while the app is active:
    • 
      # main.lov
      # Import the scheduler module that you created
      import scheduler
      
      

      def main():
      # Insert any initialization or UI setup code here.
      print("Scheduling App is starting.")

      # Start the scheduler loop to run scheduled tasks.
      scheduler.run\_scheduler()
      

      if name == "main":
      main()




  • This code initializes your app and runs the scheduler in the same process.

 
Testing Your Scheduling App
 

  • After saving all changes, click the "Run" button available in Lovable’s interface.
  • Watch the built-in console output. Every minute you should see the message "Scheduled task executed." indicating that the scheduler is working.
  • If you want to add more tasks, update the job() function or create additional scheduled jobs in the scheduler.lov file.

 
Deploying and Sharing Your App
 

  • Once you have tested your scheduling app and everything functions as expected, use Lovable’s built-in sharing options to distribute your app.
  • Each time you modify any code, save your changes and click the "Run" button to update the live app.

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation

How to Build a Scheduling API for Your Lovable App


const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

mongoose.connect('mongodb://localhost:27017/lovable', {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

const AppointmentSchema = new mongoose.Schema({
  userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  startTime: { type: Date, required: true },
  endTime: { type: Date, required: true },
  recurring: {
    repeatType: { type: String, enum: ['daily', 'weekly', 'monthly'], default: null },
    count: { type: Number, default: 0 }
  },
  createdAt: { type: Date, default: Date.now }
});

const Appointment = mongoose.model('Appointment', AppointmentSchema);

const app = express();
app.use(bodyParser.json());

app.post('/api/appointments', async (req, res) => {
  try {
    const { userId, startTime, endTime, recurring } = req.body;
    
    // Check for overlapping appointments for the same user.
    const overlapping = await Appointment.findOne({
      userId,
      $or: [
        {
          startTime: { $lt: new Date(endTime) },
          endTime: { $gt: new Date(startTime) }
        }
      ]
    });
    
    if (overlapping) {
      return res.status(400).json({ error: 'Time slot overlaps with an existing appointment' });
    }
    
    const appointment = new Appointment({ userId, startTime, endTime, recurring });
    await appointment.save();
    res.status(201).json({ success: true, appointment });
  } catch (err) {
    res.status(500).json({ error: 'Internal server error' });
  }
});

app.listen(3000, () => {
  console.log('Scheduling API running on port 3000');
});

How to Sync External Calendar Events in Your Scheduling App with Lovable


const express = require('express');
const axios = require('axios');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/lovable', {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

const ExternalEventSchema = new mongoose.Schema({
  externalId: { type: String, required: true, unique: true },
  userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  title: { type: String, required: true },
  startTime: { type: Date, required: true },
  endTime: { type: Date, required: true }
});

const ExternalEvent = mongoose.model('ExternalEvent', ExternalEventSchema);

const app = express();
app.use(bodyParser.json());

app.post('/api/webhooks/external-calendar', async (req, res) => {
  try {
    const event = req.body;
    // Assume validation of the webhook signature is done here

    const filter = { externalId: event.id };
    const update = {
      userId: event.user\_id,
      title: event.title,
      startTime: new Date(event.start\_time),
      endTime: new Date(event.end\_time)
    };

    const options = { upsert: true, new: true };
    const savedEvent = await ExternalEvent.findOneAndUpdate(filter, update, options);
    res.status(200).json({ success: true, savedEvent });
  } catch (error) {
    res.status(500).json({ error: 'Error syncing external event' });
  }
});

async function syncUserExternalEvents(userId) {
  try {
    const response = await axios.get(`https://api.externalcalendar.com/users/${userId}/events`, {
      headers: { Authorization: 'Bearer YOUR_API_TOKEN' }
    });
    const events = response.data.events;
    for (const event of events) {
      await ExternalEvent.findOneAndUpdate(
        { externalId: event.id },
        {
          userId,
          title: event.title,
          startTime: new Date(event.start\_time),
          endTime: new Date(event.end\_time)
        },
        { upsert: true, new: true }
      );
    }
  } catch (err) {
    console.error('Failed to sync events:', err.message);
  }
}

app.listen(3000, () => {
  console.log('Scheduling app API running on port 3000');
});

How to Build a Common Availability API with Lovable


const express = require('express');
const bodyParser = require('body-parser');
const moment = require('moment');
const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/lovable', { 
  useNewUrlParser: true, 
  useUnifiedTopology: true 
});

const AppointmentSchema = new mongoose.Schema({
  userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  startTime: { type: Date, required: true },
  endTime: { type: Date, required: true }
});
const Appointment = mongoose.model('Appointment', AppointmentSchema);

const app = express();
app.use(bodyParser.json());

// This endpoint calculates common available time slots for a set of users on a given day.
app.post('/api/common-availability', async (req, res) => {
  const { userIds, date, durationInMinutes } = req.body;
  try {
    const dayStart = moment(date).startOf('day');
    const dayEnd = moment(date).endOf('day');

    // Fetch all appointments for the given users on that day.
    const appointments = await Appointment.find({
      userId: { $in: userIds },
      startTime: { $gte: dayStart.toDate() },
      endTime: { $lte: dayEnd.toDate() }
    }).sort({ startTime: 1 }).exec();

    // Build busy time slots for every user.
    const busyForUser = userIds.reduce((acc, id) => {
      acc[id] = [];
      return acc;
    }, {});
    
    appointments.forEach(appt => {
      busyForUser[appt.userId.toString()].push({
        start: moment(appt.startTime),
        end: moment(appt.endTime)
      });
    });

    // Calculate free slots for one user given their busy intervals.
    function calculateFreeSlots(busyIntervals, startOfDay, endOfDay, minDuration) {
      busyIntervals.sort((a, b) => a.start - b.start);
      const free = [];
      let current = startOfDay.clone();
      busyIntervals.forEach(interval => {
        if (current.isBefore(interval.start)) {
          const freeSlot = { start: current.clone(), end: interval.start.clone() };
          if (freeSlot.end.diff(freeSlot.start, 'minutes') >= minDuration) {
            free.push(freeSlot);
          }
        }
        if (current.isBefore(interval.end)) {
          current = interval.end.clone();
        }
      });
      if (current.isBefore(endOfDay)) {
        const freeSlot = { start: current.clone(), end: endOfDay.clone() };
        if (freeSlot.end.diff(freeSlot.start, 'minutes') >= minDuration) {
          free.push(freeSlot);
        }
      }
      return free;
    }

    // Build free slots per user.
    const freeSlotsByUser = {};
    userIds.forEach(id => {
      freeSlotsByUser[id] = calculateFreeSlots(busyForUser[id], dayStart, dayEnd, durationInMinutes);
    });

    // Function to compute intersection between two lists of free slots.
    function intersectTwoSlotLists(slotsA, slotsB, minDuration) {
      let i = 0, j = 0;
      const intersections = [];
      while (i < slotsA.length && j < slotsB.length) {
        const start = moment.max(slotsA[i].start, slotsB[j].start);
        const end = moment.min(slotsA[i].end, slotsB[j].end);
        if (end.diff(start, 'minutes') >= minDuration) {
          intersections.push({ start, end });
        }
        if (slotsA[i].end.isBefore(slotsB[j].end)) {
          i++;
        } else {
          j++;
        }
      }
      return intersections;
    }

    // Intersection of free slots across all users.
    let commonSlots = freeSlotsByUser[userIds[0]];
    for (let idx = 1; idx < userIds.length; idx++) {
      commonSlots = intersectTwoSlotLists(commonSlots, freeSlotsByUser[userIds[idx]], durationInMinutes);
    }

    const availableSlots = commonSlots.map(slot => ({
      startTime: slot.start.toISOString(),
      endTime: slot.end.toISOString()
    }));

    res.json({ availableSlots });
  } catch (error) {
    res.status(500).json({ error: 'Failed to compute common availability.' });
  }
});

app.listen(3000, () => {
  console.log('Common availability API running on port 3000');
});

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free No-Code consultation

Best Practices for Building a Scheduling app with AI Code Generators

 
Overview and Introduction
 

  • This guide explains best practices for building a scheduling app that leverages AI code generators. It is written in a detailed, step-by-step fashion to help non-tech users understand each phase of the process.
  • The guide covers defining requirements, setting up the development environment, integrating AI for code generation, designing the app’s architecture, implementing features, testing, deployment, and following security practices.

 
Prerequisites
 

  • Basic understanding of applications and web services.
  • A willingness to learn new tools, even if you are not a developer.
  • Access to a computer with an internet connection.
  • Familiarity with no-code/low-code platforms or code editors is beneficial, but not required.
  • Access to an AI code generator tool or API, which will assist you in writing parts of the code base.

 
Defining App Requirements and Features
 

  • List all scheduling features your app will offer. For example:
    • User registration and authentication
    • Calendar view for scheduling appointments
    • Automated reminders
    • Integration with third-party calendars (Google Calendar, Outlook, etc.)
    • Option for recurring appointments
  • Decide on the design aid from AI. Specify where you expect the AI to generate code (e.g., for UI components or backend logic).
  • Draft a simple user flow outlining how a user books an appointment from start to finish.

 
Setting Up Your Development Environment
 

  • Select a development environment that suits your comfort level. This can range from a no-code platform to a simple code editor that integrates with AI code generators.
  • If you choose a code editor:
    • Download and install the editor (for example, Visual Studio Code).
    • Set up any necessary plugins that help integrate AI code generation, such as an API client extension.
  • Create a new project folder for your scheduling app. For beginners, a dedicated folder helps keep your work organized.

 
Integrating AI Code Generators
 

  • Choose an AI code generator tool or service that fits your project needs. This can be a built-in tool within your development platform or an external API.
  • Configure the AI tool by obtaining an API key or setting up the tool according to its documentation.
  • Test the connection with a sample code snippet. For example, you might use the tool to generate a simple piece of code:
    
    # Example: Test request to AI Code Generator API
    import requests
    
    

    api_key = "YOUR_API_KEY"
    url = "https://api.example.com/generate"
    payload = {"prompt": "Generate a simple scheduling function in Python"}
    headers = {"Authorization": f"Bearer {api_key}"}

    response = requests.post(url, json=payload, headers=headers)
    print(response.json())


 
Designing the Scheduling App Architecture
 

  • Outline the core components of your app:
    • User interface (UI) for interacting with the schedule.
    • Backend server handling data processing and storage.
    • Database to store user appointments and calendar entries.
    • Integration layer for AI-generated code and third-party calendar APIs.
  • Create a simple diagram (using paper or a digital tool) showing how these components interact.
  • <

Client trust and success are our top priorities

When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.

Rapid Dev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with. They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

CPO, Praction - Arkady Sokolov

May 2, 2023

Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost. He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Co-Founder, Arc - Donald Muir

Dec 27, 2022

Rapid Dev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space. They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Co-CEO, Grantify - Mat Westergreen-Thorne

Oct 15, 2022

Rapid Dev is an excellent developer for no-code and low-code solutions.
We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Co-Founder, Church Real Estate Marketplace - Emmanuel Brown

May 1, 2024 

Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 
This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Production Manager, Media Production Company - Samantha Fekete

Sep 23, 2022