The Ultimate Patient Appointment Manager App in .NET MAUI

Jollen Moyani - Sep 14 '23 - - Dev Community

An appointment calendar can efficiently manage and organize patient appointments in healthcare organizations. It allows healthcare professionals and staff members to easily view, track, and manage patient appointments.

In our previous blog, “Creating a .NET MAUI Hospital Appointment Booking App,” we saw how to enable patients to book appointments with their preferred doctors. In this blog, we’ll see how to create a patient appointment manager app for doctors to easily keep track of their scheduled appointments using Syncfusion .NET MAUI controls.

The app will contain the following pages:

  • Login: To enter the app using credentials.
  • Profile : To view the doctor’s contact details for members of the organization.
  • Scheduler : To display the appointments booked for a day.
  • Appointments : To summarize upcoming and past appointments.
  • Logout : To log out of the app.

Let’s see the steps to design the patient appointment manager app using Syncfusion .NET MAUI controls!

Step 1: Designing the Login page

First, we need to create a login page to allow healthcare professionals (doctors) and staff members of the organization to access the app. Refer to the following code example to create a login model to get the credentials.

LoginFormModel.cs

public class LoginFormModel
{
   [Display(Prompt = "example@mail.com", Name = "Email")]
   [EmailAddress(ErrorMessage = "Enter your email - example@mail.com")]
   public string Email { get; set; }

   [Display(Name = "Password")]
   [DataType(DataType.Password)]
   [Required(ErrorMessage = "Enter the password")]
   public string Password { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Then, initialize the login details.

ProfileViewModel.cs

public ProfileViewModel() 
{         
    this.LoginFormModel = new LoginFormModel();
}
Enter fullscreen mode Exit fullscreen mode

Now, add the Syncfusion .NET MAUI DataForm control to create the login form.

LoginPage.xaml

xmlns:dataForm="clr-namespace:Syncfusion.Maui.DataForm;assembly=Syncfusion.Maui.DataForm"
<ContentPage.BindingContext>
 <local:ProfileViewModel/>
</ContentPage.BindingContext>
<dataForm:SfDataForm x:Name="loginForm" LayoutType="TextInputLayout" Grid.Row="1" DataObject="{Binding LoginFormModel}" TextInputLayoutSettings="{dataForm:TextInputLayoutSettings FocusedStroke=#a64dff}" ValidationMode="PropertyChanged">
</dataForm:SfDataForm>
Enter fullscreen mode Exit fullscreen mode

Then, register the handler for Syncfusion Core in the MauiProgram.cs file.

MauiProgram.cs

public static MauiApp CreateMauiApp()
{
   var builder = MauiApp.CreateBuilder();
   builder.ConfigureSyncfusionCore();
}
Enter fullscreen mode Exit fullscreen mode

Login Page in .NET MAUI Patient Appointment Manager App

Login Page in .NET MAUI Patient Appointment Manager App

Refer to the following code example to validate the user credentials when selecting the LOGIN button.

LoginPage.xaml.cs

private async void loginButton_Clicked(object sender, EventArgs e)
{
   if (this.loginForm != null && App.Current?.MainPage != null)
   {
       if (this.loginForm.Validate())
       {
           App.Current.MainPage = new NavigationPage();
           App.Current.MainPage.Navigation.PushAsync(new AppShell());
       }  
   }  
}
Enter fullscreen mode Exit fullscreen mode

Note: For more details, refer to the blog “Create and Validate a Login Form in .NET MAUI.”

Once we enter the credentials and select the LOGIN button, the user credentials will be validated. Then, the validated users will be directed to the shell page containing details of the Profile , Scheduler , Appointments , and Logout pages. We can add these pages into the shell page with the help of FlyoutItem.

Refer to the following code example.

AppShell.xaml

<Shell
 …..
 <FlyoutItem Title="Profile" Icon="profilepage.png">
  <ShellContent ContentTemplate="{DataTemplate local:ProfilePage}">
  </ShellContent>
 </FlyoutItem>
 <FlyoutItem Title="Scheduler" Icon="scheduler.png">
  <ShellContent ContentTemplate="{DataTemplate local:CalendarPage}"/>
 </FlyoutItem>

 <FlyoutItem Title="Appointments" Icon="appointments.png">
  <ShellContent ContentTemplate="{DataTemplate local:AppointmentsPage}"/>
 </FlyoutItem>

 <MenuItem Clicked="MenuItem_Clicked" IconImageSource="logout.png" Text="Logout"/>
Enter fullscreen mode Exit fullscreen mode

Step 2: Designing the doctor’s profile page

After entering the credentials and clicking the LOGIN button, the user will be directed to the doctor’s Profile page to view the doctor’s contact information.

Refer to the following code example to design the doctor profile model.

Profile.cs

public class ProfileDetails
{
    [DataFormDisplayOptions(ShowLabel =false)]
    public string Image { get; set; }
    public string Name { get; set; }    
    public DateTime DOB { get; set; }
    public string Gender { get; set; }

    [Display(Name = "Blood Group")]
    public string BloodGroup { get; set; }  
    public string Email { get; set; }   
    public string Phone { get; set; }

    [DataType(DataType.MultilineText)]
    public string Address { get; set; } 
    public string City { get; set; }    
    public string State { get; set; }
    public string PostalCode { get; set; }
    public string Country { get; set; }

    [Display(Name = "Emergency Contact Name")]
    public string EmergencyContactName { get; set; }

    [Display(Name = "Emergency Contact Number")]
    public string EmergencyContactNumber { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Let’s initialize the doctor’s profile details like in the following code example.

ProfileViewModel.cs

public ProfileViewModel() { 
   this.ProfileDetails = new ProfileDetails(); 
}
Enter fullscreen mode Exit fullscreen mode

Here, we’re going to display the doctor’s profile using the Syncfusion .NET MAUI DataForm control.

ProfilePage.xaml

xmlns:dataform="clr-namespace:Syncfusion.Maui.DataForm;assembly=Syncfusion.Maui.DataForm"
<ContentPage.BindingContext>
 <local:ProfileViewModel/>
</ContentPage.BindingContext>
<dataform:SfDataForm x:Name="dataForm" IsReadOnly="True" Background="#f8f7ff" VerticalOptions="Fill" DataObject="{Binding ProfileDetails}"/>
Enter fullscreen mode Exit fullscreen mode

Doctor Profile Page

Doctor Profile Page

Step 3: Designing the scheduler page

Then, create the Scheduler page to view or edit the scheduled appointments using the Syncfusion .NET MAUI Scheduler control.

To do so, first, create an event model for the scheduler.

Appointment.cs

public class Appointment
{
    /// <summary>
    /// Gets or sets the value to display the start date.
    /// </summary>
    public DateTime From { get; set; }

    /// <summary>
    /// Gets or sets the value to display the end date.
    /// </summary>
    public DateTime To { get; set; }

    /// <summary>
    /// Gets or sets the value indicating whether the appointment is all-day.
    /// </summary>
    public bool IsAllDay { get; set; }

    /// <summary>
    /// Gets or sets the value to display the subject.
    /// </summary>
    public string EventName { get; set; }

    /// <summary>
    /// Gets or sets the value to display the background.
    /// </summary>
    public Brush Background { get; set; }

    public string Location { get; set; }

}
Enter fullscreen mode Exit fullscreen mode

Then, create the events, as seen in the following code example.

SchedulerViewModel.cs

private void IntializeAppoitments()
{
    this.Events = new ObservableCollection<Appointment>();
    Random random = new();
    List<int> randomTimeCollection = this.GettingTimeRanges();

    DateTime date;
    DateTime dateFrom = DateTime.Now.AddDays(-2);
    DateTime dateTo = DateTime.Now.AddDays(3);
    int i = 0;
    for (date = dateFrom; date < dateTo; date = date.AddDays(1))
    {
        var meeting = new Appointment();
        int hour = randomTimeCollection[random.Next(randomTimeCollection.Count)];
        meeting.From = new DateTime(date.Year, date.Month, date.Day, hour, 0, 0);
        meeting.To = meeting.From.AddHours(2);
        meeting.EventName = this.subjects.ElementAt(i);
        meeting.Background = this.GetColor(meeting.EventName);
        meeting.Location = this.GetImage(meeting.EventName);
        meeting.IsAllDay = false;
        this.Events.Add(meeting);
        i++;
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, bind the scheduler events to the AppointmentSource property.

CalendarPage.xaml

xmlns:scheduler="clr-namespace:Syncfusion.Maui.Scheduler;assembly=Syncfusion.Maui.Scheduler"

<ContentPage.BindingContext>
 <local:SchedulerViewModel/>
</ContentPage.BindingContext>

<scheduler:SfScheduler View="Week" AppointmentsSource="{Binding Events}" DisplayDate="{Binding DisplayDate}">
 <scheduler:SfScheduler.AppointmentMapping>
  <scheduler:SchedulerAppointmentMapping Subject="EventName" StartTime="From" EndTime="To" Background="Background" IsAllDay="IsAllDay"/>
 </scheduler:SfScheduler.AppointmentMapping>
</scheduler:SfScheduler>
Enter fullscreen mode Exit fullscreen mode

We can also customize the appearance of the scheduler appointments by adding images, customizing the text color, font size, and more. Refer to the following code example.

<ContentPage.Resources>
 <DataTemplate x:Key="dayAppointmentTemplate">
  <Grid RowDefinitions="0.35*,0.65*" Background="{Binding DataItem.Background}">
   <Label Text="{Binding DataItem.EventName}" VerticalOptions="Start" TextColor="White" LineBreakMode="WordWrap" Margin="5,0" FontSize="12"/>
   <Image Aspect="AspectFit" VerticalOptions="Start" Grid.Row="1" HorizontalOptions="Center" HeightRequest="30" WidthRequest="30" Source="{Binding DataItem.Location}"/>
  </Grid>
 </DataTemplate>

</ContentPage.Resources><scheduler:SfScheduler.DaysView>
 <scheduler:SchedulerDaysView AppointmentTemplate="{StaticResource dayAppointmentTemplate}"/>
</scheduler:SfScheduler.DaysView>
Enter fullscreen mode Exit fullscreen mode

Scheduler page in .NET MAUI patient appointment manager app

Scheduler page in .NET MAUI patient appointment manager app

Step 4: Listing upcoming and past appointments

Let’s design the Appointments page to list and track the upcoming and previous appointments. Refer to the following code example.

Here, we’ll add appointments in an agenda view using the Syncfusion .NET MAUI Scheduler’s agenda view.

AppointmentsPage.xaml

xmlns:scheduler="clr-namespace:Syncfusion.Maui.Scheduler;assembly=Syncfusion.Maui.Scheduler"

<ContentPage.BindingContext>
 <local:SchedulerViewModel/>
</ContentPage.BindingContext>

<scheduler:SfScheduler View="Agenda" x:Name="Scheduler" AppointmentsSource="{Binding Events}" DisplayDate="{Binding DisplayDate}">
 <scheduler:SfScheduler.AppointmentMapping>
  <scheduler:SchedulerAppointmentMapping Subject="EventName" StartTime="From" EndTime="To" Background="Background" IsAllDay="IsAllDay"/>
 </scheduler:SfScheduler.AppointmentMapping>
 <scheduler:SfScheduler.AgendaView>
  <scheduler:SchedulerAgendaView MonthHeaderTemplate="{StaticResource AgendaHeaderTemplate}"/>
 </scheduler:SfScheduler.AgendaView>
</scheduler:SfScheduler>
Enter fullscreen mode Exit fullscreen mode

Then, design the Scheduler to display the past and future appointments based on the user’s choice.

private void Button_Clicked(object sender, EventArgs e)
{
    var button = sender as Button;
    var upcomingAppointmentBorder = this.FindByName("UpcomingBorder") as BoxView;
    var pastAppointmentBordeer = this.FindByName("PastBordeer") as BoxView;

    if (button != null && button.Text == "Upcoming appointments")
    {
       var upcomingEvents = (this.BindingContext as SchedulerViewModel).Events.Where(x=>(x as Appointment).From > DateTime.Now).ToList();
       if(upcomingAppointmentBorder !=null)
       {
          upcomingAppointmentBorder.Color = Color.FromArgb("#512BD4");  
       }
       if(pastAppointmentBordeer != null)
       {
          pastAppointmentBordeer.Color = Colors.Transparent;
       }
       this.Scheduler.AppointmentsSource = upcomingEvents;
       this.Scheduler.MinimumDateTime = DateTime.Now;
       this.Scheduler.MaximumDateTime = DateTime.Now.AddDays(30);
   }
   else if (button != null && button.Text == "Past appointments")
   {
       var pastAppointments = (this.BindingContext as SchedulerViewModel).Events.Where(x => (x as Appointment).From < DateTime.Now).ToList();

        if (pastAppointmentBordeer != null)
        {
           pastAppointmentBordeer.Color = Color.FromArgb("#512BD4");
        }
        if(upcomingAppointmentBorder != null)
        {
           upcomingAppointmentBorder.Color = Colors.Transparent;
        }
        this.Scheduler.AppointmentsSource = pastAppointments;
        this.Scheduler.MinimumDateTime = DateTime.Now.AddDays(-30);
        this.Scheduler.MaximumDateTime = DateTime.Now;
   }

}
Enter fullscreen mode Exit fullscreen mode

Listing Upcoming Appointments

Listing Upcoming Appointments

Listing Past Appointments

Listing Past Appointments

Step 5: Designing the logout page

Finally, let’s create a logout module to exit the application.

AppShell.xaml

<MenuItem Clicked="MenuItem_Clicked" IconImageSource="logout.png" Text="Logout"/>
Enter fullscreen mode Exit fullscreen mode

Refer to the following code example to navigate to the login page by clicking the Logout option in the flyout item.

AppShell.xaml.cs

private void MenuItem_Clicked(object sender, EventArgs e)
{
   App.Current.MainPage = new NavigationPage();
   App.Current.MainPage.Navigation.PushAsync(new LoginPage());
}
Enter fullscreen mode Exit fullscreen mode

GitHub reference

Also, check out the complete example for creating a .NET MAUI patient appointment manager app on GitHub.

Conclusion

Thanks for reading! In this blog, we’ve seen how to create a patient appointment manager app using Syncfusion .NET MAUI controls. We’d love to hear your thoughts, so try out the steps and please leave any feedback or specific requirements in the comments section below.

If you’re not already a Syncfusion customer, you can download a free trial of Essential Studio for .NET MAUI and start evaluating its controls immediately. You can also contact us through our support forum, support portal, or feedback portal. We’re always here to assist you!

Related blogs

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .