Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reservation #2

Merged
merged 22 commits into from
Apr 6, 2024
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
25 changes: 12 additions & 13 deletions ProjectB/Models/AbstractUser.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using static BCrypt.Net.BCrypt;
using Newtonsoft.Json;

namespace ProjectB.Models;

using BCrypt.Net;
using ProjectB.Models;
using System;

/// <summary>
/// Blueprint for users, containing the fields shared by all user types. This class should be implemented by sub-classes,
Expand All @@ -12,8 +11,9 @@ namespace ProjectB.Models;
/// <param name="role">The role assigned to a user, used to determine what functionality should be available to said user.</param>
public abstract class AbstractUser(string username, UserRole role) : IEquatable<AbstractUser>, IEntity<string>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deze wijziging is niet nodig.

{
[JsonProperty] protected readonly string Username = username;
[JsonProperty] protected readonly UserRole Role = role;

[JsonProperty] protected string Username = username;
[JsonProperty] protected UserRole Role = role;

/// <summary>
/// Gets the role assigned to the user.
Expand All @@ -36,7 +36,7 @@ public UserRole GetUserRole()
/// <param name="other">The object which will be checked for equality with the object this method is called on.</param>
/// <returns>True if the objects are equal, false if not.</returns>
public abstract bool Equals(AbstractUser? other);

/// <summary>
/// Provides a more generic way to check for equality between an AbstractUser-instance and an instance of an unknown
/// type.
Expand Down Expand Up @@ -65,9 +65,9 @@ public override int GetHashCode()
private class Builder
{
private string? _username;
private string? _password;
private UserRole _role;
private DateOnly _validForDate;
private string? _password;

/// <summary>
/// Sets the username that will be set, when the Builder.Build()-method is called.
Expand All @@ -79,17 +79,16 @@ public Builder WithUsername(string username)
_username = username;
return this;
}

/// <summary>
/// Sets the password that will be set, when the Builder.Build()-method is called. Before setting the password,
/// the given value is hashed, using BCrypt's EnhancedHashPassword-method. If the role of the user is
/// the given value is hashed, using BCrypt's HashPassword-method. If the role of the user is
/// UserRole.Guest, the password will be ignored.
/// </summary>
/// <param name="password">The password that will be set.</param>
/// <returns>This instance of the Builder.</returns>
public Builder WithPassword(string password)
{
_password = BCrypt.EnhancedHashPassword(password);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gelieve wel weer EnhancedHashPassword gebruiken. Anders werkt de verification ook niet meer.

_password = EnhancedHashPassword(password);
return this;
}

Expand Down Expand Up @@ -125,10 +124,10 @@ public AbstractUser Build()
{
if (_role == UserRole.Guest)
{
return new Guest(_username!, _validForDate);
return new Guest(_username!, _validForDate, _username!);
}

return new Employee(_username!, _role, _password!);
}
}
}
}
36 changes: 23 additions & 13 deletions ProjectB/Models/Guest.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
using Newtonsoft.Json;

namespace ProjectB.Models;

public class Guest(string username, DateOnly validForDate) : AbstractUser(username, UserRole.Guest)
namespace ProjectB.Models
{
[JsonProperty] private readonly DateOnly _validForDate = validForDate;

public bool IsValid() => _validForDate.CompareTo(DateTime.Today) == 0;

public override bool Equals(AbstractUser? other)
public class Guest : AbstractUser
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Het wijzigen van de constructor is niet nodig, omdat ticketnumber geen nieuwe field hoeft te zijn. Gebruik username daarvoor.

{
if (ReferenceEquals(other, this)) return true;
if (ReferenceEquals(other, null)) return false;
if (other.GetType() != GetType()) return false;
return Username == other.GetId();
[JsonProperty]
private readonly DateOnly _validForDate;

public new string GetId() => Username;

public Guest(string username, DateOnly validForDate, string usernameParam) : base(username, UserRole.Guest)
{
_validForDate = validForDate;
this.Username = username;
}

public bool IsValid() => _validForDate.CompareTo(DateTime.Today) == 0;

public override bool Equals(AbstractUser? other)
{
if (ReferenceEquals(other, this)) return true;
if (ReferenceEquals(other, null)) return false;
if (other.GetType() != GetType()) return false;
return GetId() == other.GetId();
}
}
}
}
21 changes: 21 additions & 0 deletions ProjectB/Models/Tour.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;

namespace ProjectB.Models
{
public class Tour
{
public DateTime Time { get; set; } // Time of the tour
public string Location { get; set; } // Location of the tour
public int Capacity { get; set; } // Maximum capacity of the tour
public ICollection<Guest> Participants { get; set; } // Collection of participants signed up for the tour

public Tour(DateTime time, string location, int capacity)
{
Time = time;
Location = location;
Capacity = capacity;
Participants = new List<Guest>(); // Initialize participant collection
}
}
}
16 changes: 0 additions & 16 deletions ProjectB/Program.cs

This file was deleted.

168 changes: 168 additions & 0 deletions ProjectB/Reservation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using ProjectB.IO;
using ProjectB.Models;

public class Reservation
{
public static List<Tour> tours = new List<Tour>(); // List to store available tours
static string jsonFilePath = "signups.json";

static void Main(string[] args)
{
LoadParticipantsFromJson(); // Load sign-up data from JSON file, if exists

// Get the current hour
int currentHour = DateTime.Now.Hour;

// Create tours for each hour from the current hour to 8 PM
for (int hour = currentHour; hour <= 20; hour++)
{
DateTime tourTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hour, 0, 0);
Tour tour = new Tour(tourTime, "Your Tour Location", 13); // Initialize tours with default capacity of 13
tours.Add(tour);
}

// Register event handler to save sign-up data on application exit
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);

bool exit = false;
while (!exit)
{
Console.WriteLine("Welcome to our museum!");
Console.WriteLine("Please choose an option:");
Console.WriteLine("1. Sign up for a tour");
Console.WriteLine("2. Delete your sign-up for a tour");
Console.WriteLine("3. Exit");

int option;
while (!int.TryParse(Console.ReadLine(), out option) || (option < 1 || option > 3))
{
Console.WriteLine("Invalid input. Please enter a number between 1 and 3.");
}

switch (option)
{
case 1:
SignUpForTour();
break;
case 2:
DeleteSignUpForTour();
break;
case 3:
Console.WriteLine("Thank you for visiting our museum! Goodbye.");
exit = true;
break;
}
}
}

static void CurrentDomain_ProcessExit(object? sender, EventArgs e)
{
SaveParticipantsToJson(); // Save sign-up data on application exit
}

public static void SignUpForTour()
{
Console.WriteLine("Available Tours:");
for (int i = 0; i < tours.Count; i++)
{
int spotsLeft = tours[i].Capacity - tours[i].Participants.Count;
Console.WriteLine($"{i + 1}. Tour at {tours[i].Time.ToString("HH:mm")}, {spotsLeft} spots left");
}
Console.WriteLine("0. Go back");

Console.Write("Enter the number of the tour you want to sign up for (or 0 to go back): ");
int tourNumber;
while (!int.TryParse(Console.ReadLine(), out tourNumber) || (tourNumber < 0 || tourNumber > tours.Count))
{
Console.WriteLine($"Invalid input. Please enter a number between 0 and {tours.Count}.");
}

if (tourNumber == 0)
{
return; // Go back to main menu
}

Tour selectedTour = tours[tourNumber - 1];

if (selectedTour.Participants.Count >= selectedTour.Capacity)
{
Console.WriteLine($"Sorry, the tour at {selectedTour.Time.ToString("HH:mm")} is already fully booked.");
return;
}

Console.Write("Enter your username: ");
string? username = Console.ReadLine();

if (selectedTour.Participants.Any(p => p.GetId() == username))
{
Console.WriteLine($"Username {username} is already signed up for a tour.");

Console.Write("Do you want to change your sign-up (Y/N)? ");
string? response = Console.ReadLine()!.Trim().ToUpper();
if (response == "Y")
{
var guestToRemove = selectedTour.Participants.FirstOrDefault(p => p.GetId() == username);
if (guestToRemove != null)
{
selectedTour.Participants.Remove(guestToRemove); // Remove existing sign-up
}
}
else
{
return; // Go back to main menu
}
}

Guest guest = new Guest(username!, DateOnly.FromDateTime(DateTime.Today), username!);
selectedTour.Participants.Add(guest); // Add new sign-up

SaveParticipantsToJson(); // Save immediately after sign-up

Console.WriteLine($"You have successfully signed up for the tour at {selectedTour.Time.ToString("HH:mm")}.");
}

public static void DeleteSignUpForTour()
{
Console.Write("Enter your username to delete your sign-up: ");
string? usernameToDelete = Console.ReadLine();

foreach (var tour in tours)
{
var guestToRemove = tour.Participants.FirstOrDefault(p => p.GetId() == usernameToDelete);
if (guestToRemove != null)
{
tour.Participants.Remove(guestToRemove); // Remove sign-up

SaveParticipantsToJson(); // Save immediately after deletion

Console.WriteLine($"Your sign-up for the tour at {tour.Time.ToString("HH:mm")} has been deleted.");
return;
}
}

Console.WriteLine($"No sign-up found for username {usernameToDelete}.");
}


static void LoadParticipantsFromJson()
{
if (File.Exists(jsonFilePath))
{
string json = File.ReadAllText(jsonFilePath);
tours = JsonConvert.DeserializeObject<List<Tour>>(json)!;

}
}


static void SaveParticipantsToJson()
{ var filewriter = new JsonFileWriter<Tour>();

filewriter.WriteObjects(jsonFilePath, tours);
}
}
33 changes: 25 additions & 8 deletions ProjectB/Services/RondleidingService.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,52 @@
using System;
using ProjectB.IO;
using ProjectB.Models;
using System.IO;
using Newtonsoft.Json;

namespace ProjectB.Services
{
// Naam van de serve moet nog aangepast worden
public class RondleidingService
{
private readonly JsonFileReader _jsonFileReader;
private readonly JsonFileReader<Tour> _jsonFileReader; // Specify Tour as the type argument

public RondleidingService(JsonFileReader jsonFileReader)
public RondleidingService(JsonFileReader<Tour> jsonFileReader) // Adjust the constructor parameter
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In plaats van de data pas in te lezen wanneer je een rondleiding wil laten zien, kun je dat eigenlijk al direct doen wanneer het RondleidingService-object gemaakt wordt. Zou je in de constructor kunnen doen.

{
_jsonFileReader = jsonFileReader;
}

public void ShowRondleidingData()
{
// Replace "path/to/your/json/file.json" with the actual path to your JSON file
string jsonFilePath = "path/to/your/json/file.json";
string jsonFilePath = "C:\\Bureaublad\\C# Main\\Project-B\\ProjectB\\Database\\database.json";

try
{
// Read the JSON file using the JsonFileReader
var jsonData = _jsonFileReader.ReadJsonFile(jsonFilePath);
// Read the JSON file using the JsonFileReader<Tour>
var tourData = _jsonFileReader.ReadJsonFile(jsonFilePath);

// Display the data in the console
Console.WriteLine(jsonData);
Console.WriteLine(tourData);
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
}
}

public class JsonFileReader<T>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We hebben al een class ProjectB.IO.JsonFileReader. Die kun je gebruiken, zodat we niet dit soort code door het hele project hebben slingeren.

{
public T ReadJsonFile(string filePath)
{
if (!File.Exists(filePath))
{
throw new FileNotFoundException("JSON file not found.", filePath);
}

string jsonData = File.ReadAllText(filePath);
T deserializedData = JsonConvert.DeserializeObject<T>(jsonData)!;
return deserializedData!;
}
}
}
Loading