Adding extra section in appts screen to show details better, added appt notif on login.
All it needs now is the records sections
This commit is contained in:
parent
57359a6260
commit
1434e867bd
@ -79,7 +79,6 @@ public partial class AddOrUpdateAppointmentForm : Form
|
|||||||
|
|
||||||
private bool ValidateForm()
|
private bool ValidateForm()
|
||||||
{
|
{
|
||||||
// Ensure all required fields have values
|
|
||||||
if (string.IsNullOrWhiteSpace(titleTextBox.Text) ||
|
if (string.IsNullOrWhiteSpace(titleTextBox.Text) ||
|
||||||
string.IsNullOrWhiteSpace(descriptionTextBox.Text) ||
|
string.IsNullOrWhiteSpace(descriptionTextBox.Text) ||
|
||||||
string.IsNullOrWhiteSpace(locationTextBox.Text) ||
|
string.IsNullOrWhiteSpace(locationTextBox.Text) ||
|
||||||
@ -92,18 +91,15 @@ public partial class AddOrUpdateAppointmentForm : Form
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert start and end times to UTC for comparison
|
|
||||||
DateTime start = startPickerDate.Value.Date.Add(startPickerTime.Value.TimeOfDay).ToUniversalTime();
|
DateTime start = startPickerDate.Value.Date.Add(startPickerTime.Value.TimeOfDay).ToUniversalTime();
|
||||||
DateTime end = endPickerDate.Value.Date.Add(endPickerTime.Value.TimeOfDay).ToUniversalTime();
|
DateTime end = endPickerDate.Value.Date.Add(endPickerTime.Value.TimeOfDay).ToUniversalTime();
|
||||||
|
|
||||||
// Validate start and end times
|
|
||||||
if (start >= end)
|
if (start >= end)
|
||||||
{
|
{
|
||||||
MessageBox.Show("Start time must be before end time.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
MessageBox.Show("Start time must be before end time.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate business hours (9:00 AM - 5:00 PM EST, Monday-Friday)
|
|
||||||
TimeZoneInfo estZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
|
TimeZoneInfo estZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
|
||||||
DateTime startEST = TimeZoneInfo.ConvertTimeFromUtc(start, estZone);
|
DateTime startEST = TimeZoneInfo.ConvertTimeFromUtc(start, estZone);
|
||||||
DateTime endEST = TimeZoneInfo.ConvertTimeFromUtc(end, estZone);
|
DateTime endEST = TimeZoneInfo.ConvertTimeFromUtc(end, estZone);
|
||||||
@ -114,7 +110,6 @@ public partial class AddOrUpdateAppointmentForm : Form
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for overlapping appointments
|
|
||||||
var appointments = DatabaseHelper.RetrieveAppointments(AppState.CurrentUser.UserId);
|
var appointments = DatabaseHelper.RetrieveAppointments(AppState.CurrentUser.UserId);
|
||||||
foreach (var appt in appointments)
|
foreach (var appt in appointments)
|
||||||
{
|
{
|
||||||
@ -138,7 +133,6 @@ public partial class AddOrUpdateAppointmentForm : Form
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Gather appointment data from form
|
|
||||||
var selectedCustomer = (Customer)customerComboBox.SelectedItem!;
|
var selectedCustomer = (Customer)customerComboBox.SelectedItem!;
|
||||||
var appointment = new Appointment
|
var appointment = new Appointment
|
||||||
{
|
{
|
||||||
@ -161,13 +155,11 @@ public partial class AddOrUpdateAppointmentForm : Form
|
|||||||
|
|
||||||
if (_currentAppointment == null)
|
if (_currentAppointment == null)
|
||||||
{
|
{
|
||||||
// Add new appointment
|
|
||||||
DatabaseHelper.AddAppointment(appointment);
|
DatabaseHelper.AddAppointment(appointment);
|
||||||
MessageBox.Show("Appointment added successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
MessageBox.Show("Appointment added successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Update existing appointment
|
|
||||||
DatabaseHelper.UpdateAppointment(appointment);
|
DatabaseHelper.UpdateAppointment(appointment);
|
||||||
MessageBox.Show("Appointment updated successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
MessageBox.Show("Appointment updated successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
}
|
}
|
||||||
|
77
C969Project/AppointmentsForm.Designer.cs
generated
77
C969Project/AppointmentsForm.Designer.cs
generated
@ -37,7 +37,14 @@ partial class AppointmentsForm
|
|||||||
modifyButton = new System.Windows.Forms.Button();
|
modifyButton = new System.Windows.Forms.Button();
|
||||||
deleteButton = new System.Windows.Forms.Button();
|
deleteButton = new System.Windows.Forms.Button();
|
||||||
showAllButton = new System.Windows.Forms.Button();
|
showAllButton = new System.Windows.Forms.Button();
|
||||||
|
appointmentDetails = new System.Windows.Forms.GroupBox();
|
||||||
|
apptTitleLabel = new System.Windows.Forms.Label();
|
||||||
|
apptTypeLabel = new System.Windows.Forms.Label();
|
||||||
|
withLabel = new System.Windows.Forms.Label();
|
||||||
|
startTimeLabel = new System.Windows.Forms.Label();
|
||||||
|
endTimeLabel = new System.Windows.Forms.Label();
|
||||||
((System.ComponentModel.ISupportInitialize)appointmentDataView).BeginInit();
|
((System.ComponentModel.ISupportInitialize)appointmentDataView).BeginInit();
|
||||||
|
appointmentDetails.SuspendLayout();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// appointmentDataView
|
// appointmentDataView
|
||||||
@ -96,11 +103,71 @@ partial class AppointmentsForm
|
|||||||
showAllButton.Text = "Show All Appointments";
|
showAllButton.Text = "Show All Appointments";
|
||||||
showAllButton.UseVisualStyleBackColor = true;
|
showAllButton.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
|
// appointmentDetails
|
||||||
|
//
|
||||||
|
appointmentDetails.Controls.Add(endTimeLabel);
|
||||||
|
appointmentDetails.Controls.Add(startTimeLabel);
|
||||||
|
appointmentDetails.Controls.Add(withLabel);
|
||||||
|
appointmentDetails.Controls.Add(apptTypeLabel);
|
||||||
|
appointmentDetails.Controls.Add(apptTitleLabel);
|
||||||
|
appointmentDetails.Location = new System.Drawing.Point(773, 214);
|
||||||
|
appointmentDetails.Name = "appointmentDetails";
|
||||||
|
appointmentDetails.Size = new System.Drawing.Size(223, 320);
|
||||||
|
appointmentDetails.TabIndex = 6;
|
||||||
|
appointmentDetails.TabStop = false;
|
||||||
|
appointmentDetails.Text = "Details";
|
||||||
|
//
|
||||||
|
// apptTitleLabel
|
||||||
|
//
|
||||||
|
apptTitleLabel.Location = new System.Drawing.Point(6, 19);
|
||||||
|
apptTitleLabel.Name = "apptTitleLabel";
|
||||||
|
apptTitleLabel.Size = new System.Drawing.Size(211, 23);
|
||||||
|
apptTitleLabel.TabIndex = 0;
|
||||||
|
apptTitleLabel.Text = "Title: ";
|
||||||
|
apptTitleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// apptTypeLabel
|
||||||
|
//
|
||||||
|
apptTypeLabel.Location = new System.Drawing.Point(6, 42);
|
||||||
|
apptTypeLabel.Name = "apptTypeLabel";
|
||||||
|
apptTypeLabel.Size = new System.Drawing.Size(211, 23);
|
||||||
|
apptTypeLabel.TabIndex = 1;
|
||||||
|
apptTypeLabel.Text = "Type: ";
|
||||||
|
apptTypeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// withLabel
|
||||||
|
//
|
||||||
|
withLabel.Location = new System.Drawing.Point(6, 65);
|
||||||
|
withLabel.Name = "withLabel";
|
||||||
|
withLabel.Size = new System.Drawing.Size(211, 23);
|
||||||
|
withLabel.TabIndex = 2;
|
||||||
|
withLabel.Text = "With: ";
|
||||||
|
withLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// startTimeLabel
|
||||||
|
//
|
||||||
|
startTimeLabel.Location = new System.Drawing.Point(6, 88);
|
||||||
|
startTimeLabel.Name = "startTimeLabel";
|
||||||
|
startTimeLabel.Size = new System.Drawing.Size(211, 23);
|
||||||
|
startTimeLabel.TabIndex = 3;
|
||||||
|
startTimeLabel.Text = "Start: ";
|
||||||
|
startTimeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// endTimeLabel
|
||||||
|
//
|
||||||
|
endTimeLabel.Location = new System.Drawing.Point(6, 111);
|
||||||
|
endTimeLabel.Name = "endTimeLabel";
|
||||||
|
endTimeLabel.Size = new System.Drawing.Size(211, 23);
|
||||||
|
endTimeLabel.TabIndex = 4;
|
||||||
|
endTimeLabel.Text = "End: ";
|
||||||
|
endTimeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
// AppointmentsForm
|
// AppointmentsForm
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
ClientSize = new System.Drawing.Size(1008, 575);
|
ClientSize = new System.Drawing.Size(1008, 575);
|
||||||
|
Controls.Add(appointmentDetails);
|
||||||
Controls.Add(showAllButton);
|
Controls.Add(showAllButton);
|
||||||
Controls.Add(deleteButton);
|
Controls.Add(deleteButton);
|
||||||
Controls.Add(modifyButton);
|
Controls.Add(modifyButton);
|
||||||
@ -109,9 +176,19 @@ partial class AppointmentsForm
|
|||||||
Controls.Add(appointmentDataView);
|
Controls.Add(appointmentDataView);
|
||||||
Text = "AppointmentsForm";
|
Text = "AppointmentsForm";
|
||||||
((System.ComponentModel.ISupportInitialize)appointmentDataView).EndInit();
|
((System.ComponentModel.ISupportInitialize)appointmentDataView).EndInit();
|
||||||
|
appointmentDetails.ResumeLayout(false);
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private System.Windows.Forms.Label apptTypeLabel;
|
||||||
|
private System.Windows.Forms.Label withLabel;
|
||||||
|
private System.Windows.Forms.Label startTimeLabel;
|
||||||
|
private System.Windows.Forms.Label endTimeLabel;
|
||||||
|
|
||||||
|
private System.Windows.Forms.Label apptTitleLabel;
|
||||||
|
|
||||||
|
private System.Windows.Forms.GroupBox appointmentDetails;
|
||||||
|
|
||||||
private System.Windows.Forms.Button showAllButton;
|
private System.Windows.Forms.Button showAllButton;
|
||||||
|
|
||||||
private System.Windows.Forms.DataGridView appointmentDataView;
|
private System.Windows.Forms.DataGridView appointmentDataView;
|
||||||
|
@ -20,6 +20,8 @@ public partial class AppointmentsForm : Form
|
|||||||
deleteButton.Click += DeleteButtonOnClick;
|
deleteButton.Click += DeleteButtonOnClick;
|
||||||
addButton.Click += AddButtonOnClick;
|
addButton.Click += AddButtonOnClick;
|
||||||
modifyButton.Click += ModifyButtonOnClick;
|
modifyButton.Click += ModifyButtonOnClick;
|
||||||
|
|
||||||
|
appointmentDataView.SelectionChanged += UpdateAppointmentDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ModifyButtonOnClick(object? sender, EventArgs e)
|
private void ModifyButtonOnClick(object? sender, EventArgs e)
|
||||||
@ -74,4 +76,16 @@ public partial class AppointmentsForm : Form
|
|||||||
List<Appointment>? selectedAppointments = _appointments.Where(a => a.Start == date).ToList();
|
List<Appointment>? selectedAppointments = _appointments.Where(a => a.Start == date).ToList();
|
||||||
appointmentDataView.DataSource = selectedAppointments?.Count > 0 ? selectedAppointments : null;
|
appointmentDataView.DataSource = selectedAppointments?.Count > 0 ? selectedAppointments : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateAppointmentDetails(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (appointmentDataView.CurrentRow?.DataBoundItem is Appointment appointment)
|
||||||
|
{
|
||||||
|
apptTitleLabel.Text = $"Title: {appointment.Title}";
|
||||||
|
apptTypeLabel.Text = $"Type: {appointment.AppointmentType}";
|
||||||
|
withLabel.Text = $"With: {DatabaseHelper.RetrieveCustomer(appointment.CustomerId)?.CustomerName ?? "Unknown"}";
|
||||||
|
startTimeLabel.Text = $"Start: {appointment.Start.ToLocalTime():MM/dd/yyyy hh:mm tt} {TimeZoneInfo.Local.Id}";
|
||||||
|
endTimeLabel.Text = $"End: {appointment.End.ToLocalTime():MM/dd/yyyy hh:mm tt} {TimeZoneInfo.Local.Id}";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -17,7 +17,7 @@
|
|||||||
<Compile Update="DashboardForm.cs">
|
<Compile Update="DashboardForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Update="RecordsForm.cs">
|
<Compile Update="CustomersForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Update="AddUpdateCustomerForm.cs">
|
<Compile Update="AddUpdateCustomerForm.cs">
|
||||||
@ -29,6 +29,9 @@
|
|||||||
<Compile Update="AddOrUpdateAppointmentForm.cs">
|
<Compile Update="AddOrUpdateAppointmentForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Update="ReportsForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -2,7 +2,7 @@ using System.ComponentModel;
|
|||||||
|
|
||||||
namespace C969Project;
|
namespace C969Project;
|
||||||
|
|
||||||
partial class RecordsForm
|
partial class CustomersForm
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required designer variable.
|
/// Required designer variable.
|
@ -3,12 +3,12 @@ using C969Project.Data.Models;
|
|||||||
|
|
||||||
namespace C969Project;
|
namespace C969Project;
|
||||||
|
|
||||||
public partial class RecordsForm : Form
|
public partial class CustomersForm : Form
|
||||||
{
|
{
|
||||||
private List<Customer>? _customers;
|
private List<Customer>? _customers;
|
||||||
private AddUpdateCustomerForm _form = new();
|
private AddUpdateCustomerForm _form = new();
|
||||||
|
|
||||||
public RecordsForm()
|
public CustomersForm()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
UpdateCustomersList(null, EventArgs.Empty);
|
UpdateCustomersList(null, EventArgs.Empty);
|
@ -2,20 +2,20 @@ namespace C969Project;
|
|||||||
|
|
||||||
public partial class DashboardForm : Form
|
public partial class DashboardForm : Form
|
||||||
{
|
{
|
||||||
private RecordsForm _recordsForm;
|
private CustomersForm _customersForm;
|
||||||
private AppointmentsForm _appointmentsForm;
|
private AppointmentsForm _appointmentsForm;
|
||||||
|
|
||||||
public DashboardForm()
|
public DashboardForm()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
_recordsForm = new RecordsForm();
|
_customersForm = new CustomersForm();
|
||||||
_appointmentsForm = new AppointmentsForm();
|
_appointmentsForm = new AppointmentsForm();
|
||||||
|
|
||||||
CustomersButton.Click += (sender, args) =>
|
CustomersButton.Click += (sender, args) =>
|
||||||
{
|
{
|
||||||
_recordsForm.ShowDialog();
|
_customersForm.ShowDialog();
|
||||||
_recordsForm.UpdateCustomersList(null, EventArgs.Empty);
|
_customersForm.UpdateCustomersList(null, EventArgs.Empty);
|
||||||
};
|
};
|
||||||
|
|
||||||
AppointmentsButton.Click += (sender, args) =>
|
AppointmentsButton.Click += (sender, args) =>
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
using System;
|
|
||||||
using System.Data;
|
|
||||||
using MySql.Data.MySqlClient;
|
using MySql.Data.MySqlClient;
|
||||||
using C969Project.Data.Models;
|
using C969Project.Data.Models;
|
||||||
|
|
||||||
namespace C969Project.Data
|
namespace C969Project.Data;
|
||||||
{
|
|
||||||
public static class DatabaseHelper
|
public static class DatabaseHelper
|
||||||
{
|
{
|
||||||
private static string ConnectionString => AppSettings.GetSetting("ConnectionStrings", "DefaultConnection");
|
private static string ConnectionString => AppSettings.GetSetting("ConnectionStrings", "DefaultConnection");
|
||||||
@ -18,7 +16,8 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException ex)
|
catch (MySqlException ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine(ex.Message);
|
MessageBox.Show($"Database connection error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string query = "SELECT * FROM client_schedule.user WHERE userName = @username";
|
string query = "SELECT * FROM client_schedule.user WHERE userName = @username";
|
||||||
@ -52,8 +51,8 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
MessageBox.Show($"Database connection error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
return new List<Customer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Customer> customers = new List<Customer>();
|
List<Customer> customers = new List<Customer>();
|
||||||
@ -80,6 +79,42 @@ namespace C969Project.Data
|
|||||||
return customers;
|
return customers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Customer? RetrieveCustomer(int customerId)
|
||||||
|
{
|
||||||
|
using MySqlConnection connection = new MySqlConnection(AppSettings.GetSetting("ConnectionStrings", "DefaultConnection"));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
connection.Open();
|
||||||
|
}
|
||||||
|
catch (MySqlException e)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Database connection error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string query = "SELECT * FROM client_schedule.customer WHERE customerId = @customerId";
|
||||||
|
using MySqlCommand command = new MySqlCommand(query, connection);
|
||||||
|
command.Parameters.AddWithValue("@customerId", customerId);
|
||||||
|
|
||||||
|
using MySqlDataReader reader = command.ExecuteReader();
|
||||||
|
if (reader.Read())
|
||||||
|
{
|
||||||
|
return new Customer
|
||||||
|
{
|
||||||
|
CustomerId = reader.GetInt32("customerId"),
|
||||||
|
CustomerName = reader.GetString("customerName"),
|
||||||
|
AddressId = reader.GetInt32("addressId"),
|
||||||
|
Active = reader.GetInt32("active"),
|
||||||
|
CreateDate = reader.GetDateTime("createDate"),
|
||||||
|
CreatedBy = reader.GetString("createdBy"),
|
||||||
|
LastUpdate = reader.GetDateTime("lastUpdate"),
|
||||||
|
LastUpdateBy = reader.GetString("lastUpdateBy"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static int AddCustomer(Customer customer)
|
public static int AddCustomer(Customer customer)
|
||||||
{
|
{
|
||||||
int customerId = 0;
|
int customerId = 0;
|
||||||
@ -110,13 +145,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
return customerId;
|
return customerId;
|
||||||
}
|
}
|
||||||
@ -144,13 +177,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,13 +198,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,8 +223,8 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
MessageBox.Show($"Database connection error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string query = "SELECT * FROM client_schedule.address WHERE addressId = @addressId";
|
string query = "SELECT * FROM client_schedule.address WHERE addressId = @addressId";
|
||||||
@ -235,8 +264,8 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
MessageBox.Show($"Database connection error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
return new List<Address>();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Address> addresses = new List<Address>();
|
List<Address> addresses = new List<Address>();
|
||||||
@ -297,13 +326,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
return addressId;
|
return addressId;
|
||||||
}
|
}
|
||||||
@ -333,13 +360,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,13 +381,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,8 +407,8 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
MessageBox.Show($"Database connection error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string query = "SELECT * FROM client_schedule.appointment WHERE appointmentId = @appointmentId";
|
string query = "SELECT * FROM client_schedule.appointment WHERE appointmentId = @appointmentId";
|
||||||
@ -430,8 +453,8 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
MessageBox.Show($"Database connection error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
return new List<Appointment>();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Appointment> appointments = new List<Appointment>();
|
List<Appointment> appointments = new List<Appointment>();
|
||||||
@ -502,13 +525,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,13 +565,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,13 +586,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,8 +611,8 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
MessageBox.Show($"Database connection error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string query = "SELECT * FROM client_schedule.city WHERE cityId = @cityId";
|
string query = "SELECT * FROM client_schedule.city WHERE cityId = @cityId";
|
||||||
@ -632,8 +649,8 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
MessageBox.Show($"Database connection error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
return new List<City>();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<City> cities = new List<City>();
|
List<City> cities = new List<City>();
|
||||||
@ -682,7 +699,7 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Error getting city ID: {ex.Message}");
|
MessageBox.Show($"Error getting city ID: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
return cityId;
|
return cityId;
|
||||||
}
|
}
|
||||||
@ -716,13 +733,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
return cityId;
|
return cityId;
|
||||||
}
|
}
|
||||||
@ -749,13 +764,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,13 +785,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,8 +809,8 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
MessageBox.Show($"Database connection error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string query = "SELECT * FROM client_schedule.country WHERE countryId = @countryId";
|
string query = "SELECT * FROM client_schedule.country WHERE countryId = @countryId";
|
||||||
@ -835,8 +846,8 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
MessageBox.Show($"Database connection error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
return new List<Country>();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Country> countries = new List<Country>();
|
List<Country> countries = new List<Country>();
|
||||||
@ -883,7 +894,7 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Error getting country ID: {ex.Message}");
|
MessageBox.Show($"Error getting country ID: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
return countryId;
|
return countryId;
|
||||||
}
|
}
|
||||||
@ -916,13 +927,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
return countryId;
|
return countryId;
|
||||||
}
|
}
|
||||||
@ -948,13 +957,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,13 +978,11 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"MySQL Error: {e.Message}");
|
MessageBox.Show($"MySQL Error: {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"General Error: {ex.Message}");
|
MessageBox.Show($"General Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -987,4 +992,4 @@ namespace C969Project.Data
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
|
@ -34,12 +34,44 @@ namespace C969Project
|
|||||||
Console.WriteLine($"Login successful, {usr.Username}");
|
Console.WriteLine($"Login successful, {usr.Username}");
|
||||||
AppState.CurrentUser = usr;
|
AppState.CurrentUser = usr;
|
||||||
|
|
||||||
|
CheckForAppointments();
|
||||||
|
|
||||||
var dash = new DashboardForm();
|
var dash = new DashboardForm();
|
||||||
dash.FormClosing += (o, args) => { Close(); };
|
dash.FormClosing += (o, args) => { Close(); };
|
||||||
dash.Show();
|
dash.Show();
|
||||||
Hide();
|
Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CheckForAppointments()
|
||||||
|
{
|
||||||
|
if (AppState.CurrentUser is null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("No user logged in, cannot check for appointments.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var appointments = DatabaseHelper.RetrieveAppointments(AppState.CurrentUser.UserId);
|
||||||
|
|
||||||
|
DateTime nowUtc = DateTime.UtcNow;
|
||||||
|
DateTime fifteenMinutesFromNowUtc = nowUtc.AddMinutes(15);
|
||||||
|
|
||||||
|
var upcoming = appointments
|
||||||
|
.Where(a => a.Start >= nowUtc && a.Start <= fifteenMinutesFromNowUtc)
|
||||||
|
.OrderBy(a => a.Start)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (upcoming.Any())
|
||||||
|
{
|
||||||
|
var appt = upcoming.First();
|
||||||
|
DateTime localStart = appt.Start.ToLocalTime();
|
||||||
|
MessageBox.Show(
|
||||||
|
$"You have an upcoming {appt.AppointmentType} appointment '{appt.Title}' at {localStart}.",
|
||||||
|
"Upcoming Appointment",
|
||||||
|
MessageBoxButtons.OK,
|
||||||
|
MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateLoginButtonState()
|
private void UpdateLoginButtonState()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(usernameTextBox.Text) || string.IsNullOrEmpty(passwordTextBox.Text))
|
if (string.IsNullOrEmpty(usernameTextBox.Text) || string.IsNullOrEmpty(passwordTextBox.Text))
|
||||||
|
41
C969Project/ReportsForm.Designer.cs
generated
Normal file
41
C969Project/ReportsForm.Designer.cs
generated
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace C969Project;
|
||||||
|
|
||||||
|
partial class ReportsForm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(800, 450);
|
||||||
|
this.Text = "ReportsForm";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
9
C969Project/ReportsForm.cs
Normal file
9
C969Project/ReportsForm.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace C969Project;
|
||||||
|
|
||||||
|
public partial class ReportsForm : Form
|
||||||
|
{
|
||||||
|
public ReportsForm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
75
C969Project/todo.md
Normal file
75
C969Project/todo.md
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# ✅ C# Application Development To-Do List
|
||||||
|
|
||||||
|
## 1. Login Form
|
||||||
|
|
||||||
|
- [x] Create a login form with the following functionality:
|
||||||
|
- [x] Determine a user’s location.
|
||||||
|
- [x] Translate login and error control messages into:
|
||||||
|
- [x] English
|
||||||
|
- [x] One additional language
|
||||||
|
- [x] Verify correct username and password.
|
||||||
|
|
||||||
|
## 2. Customer Record Management
|
||||||
|
|
||||||
|
- [x] Add functionality to:
|
||||||
|
- [x] Add customer records
|
||||||
|
- [x] Update customer records
|
||||||
|
- [x] Delete customer records
|
||||||
|
|
||||||
|
- [x] Validate customer record requirements:
|
||||||
|
- [x] Include name, address, and phone number fields.
|
||||||
|
- [x] Ensure fields are trimmed and non-empty.
|
||||||
|
- [x] Restrict phone number field to digits and dashes only.
|
||||||
|
|
||||||
|
- [x] Add exception handling for:
|
||||||
|
- [x] Add operations
|
||||||
|
- [x] Update operations
|
||||||
|
- [x] Delete operations
|
||||||
|
|
||||||
|
## 3. Appointment Management
|
||||||
|
|
||||||
|
- [x] Add functionality to:
|
||||||
|
- [x] Add appointments
|
||||||
|
- [x] Update appointments
|
||||||
|
- [x] Delete appointments
|
||||||
|
- [x] Capture appointment type
|
||||||
|
- [x] Link each appointment to a specific customer
|
||||||
|
|
||||||
|
- [x] Validate appointment requirements:
|
||||||
|
- [x] Appointments must be during business hours (9:00 a.m. – 5:00 p.m., Monday–Friday, EST).
|
||||||
|
- [x] Prevent scheduling of overlapping appointments.
|
||||||
|
|
||||||
|
- [x] Add exception handling for:
|
||||||
|
- [x] Add operations
|
||||||
|
- [x] Update operations
|
||||||
|
- [x] Delete operations
|
||||||
|
|
||||||
|
## 4. Calendar View
|
||||||
|
|
||||||
|
- [x] Implement a calendar view:
|
||||||
|
- [x] Allow selection of a day of the month
|
||||||
|
- [x] Display appointments for that specific day
|
||||||
|
|
||||||
|
## 5. Time Zone Adjustment
|
||||||
|
|
||||||
|
- [x] Automatically adjust appointment times based on:
|
||||||
|
- [x] User time zones
|
||||||
|
- [x] Daylight saving time
|
||||||
|
|
||||||
|
## 6. Appointment Alerts
|
||||||
|
|
||||||
|
- [x] Create a function to:
|
||||||
|
- [x] Generate an alert when a user with an appointment within 15 minutes logs in
|
||||||
|
|
||||||
|
## 7. Reports
|
||||||
|
|
||||||
|
- [ ] Create a report generator using collection classes and lambda expressions:
|
||||||
|
- [ ] Report: Number of appointment types by month
|
||||||
|
- [ ] Report: Schedule for each user
|
||||||
|
- [ ] Report: One additional report of your choice
|
||||||
|
|
||||||
|
## 8. Login History
|
||||||
|
|
||||||
|
- [x] Record each login attempt:
|
||||||
|
- [x] Include timestamp and username
|
||||||
|
- [x] Append to “Login_History.txt” file
|
Loading…
Reference in New Issue
Block a user