diff --git a/.idea/misc.xml b/.idea/misc.xml index fdc35ea..0c04b52 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/src/main/java/org/codedifferently/AmaniAppointment.java b/src/main/java/org/codedifferently/AmaniAppointment.java new file mode 100644 index 0000000..93f2804 --- /dev/null +++ b/src/main/java/org/codedifferently/AmaniAppointment.java @@ -0,0 +1,262 @@ +package org.codedifferently; + +import java.util.ArrayList; +import java.util.Scanner; + +// Defines the AmaniAppointmentMenu class that manages appointment scheduling and tracking. +public class AmaniAppointment { + + // Stores all available appointment time slots for the day. + private static final String[] TIME_SLOTS = { + "9:00 AM", "9:30 AM", "10:00 AM", "10:30 AM", + "11:00 AM", "11:30 AM", "12:00 PM", "12:30 PM", + "1:00 PM", "1:30 PM", "2:00 PM", "2:30 PM", + "3:00 PM", "3:30 PM", "4:00 PM", "4:30 PM", + "5:00 PM" + }; + + // Stores all scheduled appointments in a shared list. + private static final ArrayList appointments = new ArrayList<>(); + + // Stores the customer’s name for the appointment. + private String name; + + // Stores the haircut or service selected for the appointment. + private String haircut; + + // Stores the selected time slot for the appointment. + private String timeSlot; + + // Stores the unique customer ID associated with the appointment. + private String customerId; + + // Tracks whether the customer has checked in for the appointment. + private boolean checkedIn; + + // Constructor to instantiate a new AmaniAppointmentMenu object using customer and appointment details. + public AmaniAppointment(BobbyPatient customer, String haircut, String timeSlot) { + this.name = customer.getName(); + this.haircut = haircut; + this.timeSlot = timeSlot; + this.customerId = customer.getCustomerId(); + this.checkedIn = false; + } + + // Displays the appointment menu and processes user selections until the user exits. + public static ArrayList appointmentMenu(BobbyPatient customer, Scanner scanner) { + boolean running = true; + + while (running) { + System.out.println("\n=== Appointment Menu ==="); + System.out.println("1) Schedule Appointment"); + System.out.println("2) Cancel Appointment"); + System.out.println("3) Check In"); + System.out.println("4) View Schedule"); + System.out.println("0) Exit"); + System.out.print("Choose: "); + + int choice = readInt(scanner); + + // Creates a temporary appointment object to access instance methods. + AmaniAppointment temp = new AmaniAppointment(customer, "N/A", "N/A"); + + switch (choice) { + case 1 -> temp.scheduleAppointment(customer, scanner); + case 2 -> temp.cancelAppointment(customer); + case 3 -> temp.checkIn(customer); + case 4 -> temp.viewSchedule(); + case 0 -> running = false; + default -> System.out.println("Invalid option."); + } + } + + // Returns the list of all scheduled appointments. + return appointments; + } + + // Schedules a new appointment if the selected slot and customer are valid. + public void scheduleAppointment(BobbyPatient customer, Scanner scanner) { + System.out.println("\n--- Schedule Appointment ---"); + + int slotIndex = promptForSlot(scanner); + String slot = TIME_SLOTS[slotIndex]; + + // Checks whether the selected time slot is already booked. + if (findAppointmentBySlot(slot) != null) { + System.out.println("That time slot is already booked. Pick another."); + return; + } + + // Checks whether the customer already has an existing appointment. + AmaniAppointment existing = findAppointmentByCustomer(customer.getCustomerId()); + // Tells the customer to reschedule if they already have an appointment. + if (existing != null) { + System.out.println("You already have an appointment at " + existing.timeSlot + "."); + System.out.println("Cancel it first if you want to reschedule."); + return; + } + + // Prompts the user to enter the haircut that they want. + System.out.print("Enter haircut/service (ex: Fade, Trim, Lineup): "); + String haircutInput = scanner.nextLine().trim(); + + // Validates that the haircut input is not empty. + while (haircutInput.isEmpty()) { + System.out.print("Service cannot be empty. Enter haircut/service: "); + haircutInput = scanner.nextLine().trim(); + } + + // Adds the new appointment to the appointments list. + appointments.add(new AmaniAppointment(customer, haircutInput, slot)); + + System.out.println("\nBooked! " + customer.getName() + " at " + slot + " for " + haircutInput + "."); + } + + // Cancels customer’s existing appointment if one exists. + public void cancelAppointment(BobbyPatient customer) { + System.out.println("\n--- Cancel Appointment ---"); + + // Finds the appointment for the customer provided as an argument + AmaniAppointment appt = findAppointmentByCustomer(customer.getCustomerId()); + + // Checks whether an appointment exists for the customer. + if (appt == null) { + System.out.println("No appointment found for " + customer.getName() + "."); + return; + } + + // Removes the appointment from the appointments list. + appointments.remove(appt); + + System.out.println("Canceled appointment at " + appt.timeSlot + " for " + customer.getName() + "."); + } + + // Marks the customer as checked in for their appointment. + public void checkIn(BobbyPatient customer) { + System.out.println("\n--- Check In ---"); + + AmaniAppointment appt = findAppointmentByCustomer(customer.getCustomerId()); + + // Checks whether an appointment exists before checking in. + if (appt == null) { + System.out.println("No appointment found for " + customer.getName() + "."); + return; + } + + // Updates the appointment’s checked-in status to true. + appt.setCheckedIn(true); + + System.out.println("Checked in: " + appt.name + " | " + appt.timeSlot + " | " + appt.haircut); + } + + // Displays the full schedule and indicates whether each slot is available or booked. + public void viewSchedule() { + System.out.println("\n--- Full Schedule ---"); + + for (String slot : TIME_SLOTS) { + AmaniAppointment appt = findAppointmentBySlot(slot); + + // Displays availability if no appointment exists for the slot. + if (appt == null) { + System.out.println(slot + " -> Available"); + } else { + // Changes output depending on whether the customer has checked in for their appointment. + if (appt.checkedIn) { + System.out.println(slot + " -> BOOKED " + appt.name + " (" + appt.haircut + ") Checked In?: Yes"); + } else { + System.out.println(slot + " -> BOOKED " + appt.name + " (" + appt.haircut + ") Checked In?: No"); + } + } + } + } + + // Prompts the user to select a valid time slot number. + private int promptForSlot(Scanner scanner) { + System.out.println("Available time slots:"); + + for (int i = 0; i < TIME_SLOTS.length; i++) { + System.out.println((i + 1) + ") " + TIME_SLOTS[i]); + } + + System.out.print("Pick a slot number (1-" + TIME_SLOTS.length + "): "); + int slotNum = readInt(scanner); + + // Validates that the selected slot number is within range. + while (slotNum < 1 || slotNum > TIME_SLOTS.length) { + System.out.println("Invalid slot. Pick 1-" + TIME_SLOTS.length + ": "); + slotNum = readInt(scanner); + } + + // Returns the zero-based index of the selected slot. + return slotNum - 1; + } + + // Reads and validates an integer input from the user. + private static int readInt(Scanner scanner) { + while (!scanner.hasNextInt()) { + scanner.nextLine(); + System.out.println("Enter a number: "); + } + + int val = scanner.nextInt(); + scanner.nextLine(); + return val; + } + + // Searches for an appointment by time slot and returns it if found. + private static AmaniAppointment findAppointmentBySlot(String slot) { + for (AmaniAppointment appt : appointments) { + if (appt.timeSlot.equals(slot)) { + return appt; + } + } + return null; + } + + // Searches for an appointment by customer ID and returns it if found. + private static AmaniAppointment findAppointmentByCustomer(String customerId) { + for (AmaniAppointment appt : appointments) { + if (appt.customerId.equals(customerId)) { + return appt; + } + } + return null; + } + + // Returns a formatted string representation of the appointment. + @Override + public String toString() { + return "Appointment{name='" + name + "', customerId='" + customerId + + "', timeSlot='" + timeSlot + "', haircut='" + haircut + "'}"; + } + + // Returns the checked-in status of the appointment. + public boolean getCheckedIn() { + return this.checkedIn; + } + + // Updates the checked-in status of the appointment. + public void setCheckedIn(boolean checkedIn) { + this.checkedIn = checkedIn; + } + + // Returns the customer’s name associated with the appointment. + public String getName() { + return this.name; + } + + // Returns the customer ID associated with the appointment. + public String getCustomerId() { + return this.customerId; + } + + // Returns the haircut or service associated with the appointment. + public String getHaircut() { + return this.haircut; + } + + // Returns the time slot associated with the appointment. + public String getTimeSlot() { + return this.timeSlot; + } +} \ No newline at end of file diff --git a/src/main/java/org/codedifferently/BobbyPatient.java b/src/main/java/org/codedifferently/BobbyPatient.java new file mode 100644 index 0000000..9dc2fd8 --- /dev/null +++ b/src/main/java/org/codedifferently/BobbyPatient.java @@ -0,0 +1,56 @@ +package org.codedifferently; + +import java.util.Random; + +// Defines the BobbyPatient class that stores customer information and generates unique IDs. +public class BobbyPatient { + + // Stores the customer’s full name. + private String name; + + // Stores the customer’s phone number. + private String phoneNumber; + + // Stores the unique patient ID that remains constant after creation. + private final String customerId; + + /* Constructor to instantiates a new BobbyPatient object using the provided name and phone number. + Generates and assigns a unique customer ID during object creation. */ + public BobbyPatient(String name, String phoneNumber) { + this.name = name; + this.phoneNumber = phoneNumber; + this.customerId = generateCustomerId(new Random()); + } + + // Returns the customer’s name. + public String getName() { + return name; + } + + // Returns the customer’s phone number. + public String getPhoneNumber() { + return phoneNumber; + } + + // Returns the customer’s unique ID. + public String getCustomerId() { + return customerId; + } + + // Generates a unique customer ID using the first three letters of the name and a random five-digit number. + public String generateCustomerId(Random random) { + String prefix; + if (name.length() >= 3) { + prefix = name.substring(0, 3).toUpperCase(); + } else { + prefix = name.toUpperCase(); + } + return prefix + random.nextInt(10000, 100000); + } + + // Returns a formatted string representation of the customer’s information. + @Override + public String toString() { + return "\n(Name: " + name + ", Phone: " + phoneNumber + ", Customer Id: " + customerId + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/org/codedifferently/JaydenClinicApp.java b/src/main/java/org/codedifferently/JaydenClinicApp.java new file mode 100644 index 0000000..d15b26c --- /dev/null +++ b/src/main/java/org/codedifferently/JaydenClinicApp.java @@ -0,0 +1,9 @@ +package org.codedifferently; +import java.util.Scanner; + +public class JaydenClinicApp { + public static void main(String[] args) { + // Launches the barbershop system. + JaydenClinicSystem.displayOptions(new Scanner(System.in)); + } +} diff --git a/src/main/java/org/codedifferently/JaydenClinicSystem.java b/src/main/java/org/codedifferently/JaydenClinicSystem.java new file mode 100644 index 0000000..d076881 --- /dev/null +++ b/src/main/java/org/codedifferently/JaydenClinicSystem.java @@ -0,0 +1,188 @@ +package org.codedifferently; + +import java.util.ArrayList; +import java.util.Scanner; +import java.util.regex.*; + +// Defines the main clinic system that manages customers. +public class JaydenClinicSystem { + + // Stores all registered customers in the system. + private static ArrayList customers = new ArrayList<>(); + + // Displays the main menu and processes user selections until the user quits. + public static void displayOptions(Scanner sc) { + System.out.println("Welcome! What would you like to do today? (Enter a number)"); + int input; + + // Stores appointment data for generating a journal upon exit. + ArrayList appointments = null; + + do { + // Displays the main menu options to the user. + System.out.println("\n=== Barber Shop Management Menu ==="); + System.out.println("1) Add a new customer"); + System.out.println("2) View all customers"); + System.out.println("3) Manage appointment for a customer"); + System.out.println("4) Search for a customer"); + System.out.println("0) Quit"); + System.out.print("Choose: "); + + // Validates numeric input before processing. + if (sc.hasNextInt()) { + input = sc.nextInt(); + } else { + input = -1; + } + sc.nextLine(); + + // Defines the regex pattern used to validate phone number input. + String phoneRegex = "^\\+?1?\\D*?(\\d{3})\\D*?(\\d{3})\\D*?(\\d{4})$"; + + // Compiles the regex string into a Pattern object. + Pattern phonePattern = Pattern.compile(phoneRegex); + + String name; + String phoneNumber; + + switch (input) { + // Handles the creation and storage of a new customer. + case 1: + name = validateName(sc); + phoneNumber = formatPhoneNumber(phonePattern, sc); + addCustomer(new BobbyPatient(name, phoneNumber)); + break; + // Displays the full list of registered customers. + case 2: + System.out.println("\nCustomers"); + System.out.println(getCustomers()); + break; + // Manages appointment scheduling for an existing customer. + case 3: + phoneNumber = formatPhoneNumber(phonePattern, sc); + BobbyPatient customer = searchCustomer(phoneNumber, sc); + if (customer != null) { + appointments = AmaniAppointment.appointmentMenu(customer, sc); + } else { + System.out.println("\nCustomer not in database. Please add them first."); + } + break; + // Searches for a customer using their phone number. + case 4: + phoneNumber = formatPhoneNumber(phonePattern, sc); + BobbyPatient customer2 = searchCustomer(phoneNumber, sc); + + // Prints out customer if found. + if (customer2 != null) { + System.out.println("\nCustomer found: " + customer2); + // Tells the user that the customer was not found if they do not exist. + } else { + System.out.println("\nCustomer not found."); + } + break; + // Exits the system and prints a journal of completed appointments. + case 0: + // Prints out electronic journal if appointments have happened today. + if (appointments != null && !(appointments.isEmpty())) { + System.out.println("\nElectronic Journal of Completed Appointments"); + for (AmaniAppointment appt: appointments) { + if (appt.getCheckedIn()) { + System.out.println(appt.getTimeSlot() + " -> [Name: " + appt.getName() + ", " + + "Customer Id: " + appt.getCustomerId() + ", " + + "Haircut: " + appt.getHaircut() + "]"); + } + } + } + System.out.println("\nExiting system..."); + break; + + // Handles invalid menu selections. + default: + System.out.println("\nPlease select a valid option."); + } + // Stopping condition. Program will exit when the user inputs 0. + } while (input != 0); + } + + // Adds a new customer to the customer list. + public static void addCustomer(BobbyPatient customer) { + customers.add(customer); + System.out.println("\nCustomer " + customer.getName() + " (" + customer.getCustomerId() + ") added!"); + } + + // Returns the list of all registered customers. + public static ArrayList getCustomers() { + return customers; + } + + // Searches for a customer using their phone number and returns the match if found. + public static BobbyPatient searchCustomer(String phoneNumber, Scanner sc) { + ArrayList customersFound = new ArrayList<>(); + for (BobbyPatient customer : customers) { + if (customer.getPhoneNumber().equals(phoneNumber)) { + customersFound.add(customer); + } + } + // Returns null if the customer is not found. + if (customersFound.isEmpty()) { + return null; + // Returns the customer if there are no duplicate phone numbers. + } else if (customersFound.size() == 1) { + return customersFound.getFirst(); + // Prompts the user to select by customer id since more than one customer used the same phone number. + } else { + System.out.println("\nMultiple customers found: " + customersFound + "\n"); + while(true) { + System.out.print("Enter customer id (CASE SENSITIVE): "); + String id = sc.nextLine(); + for (BobbyPatient customer : customers) { + if (customer.getCustomerId().equals(id)) { + return customer; + } + } + System.out.println("Invalid customer id. Try again.\n"); + } + } + } + + // Validates that the user's name input contains only permitted characters. + public static String validateName(Scanner sc) { + // Repeats continuously until valid input is provided. + while (true) { + // Prompts the user to enter their name. + System.out.print("\nEnter a name: "); + String name = sc.nextLine(); + + // Checks whether the input matches the required name pattern. + // Allows letters and optionally single spaces, hyphens, or apostrophes between words. + if (name.matches("^[a-zA-Z]+([ '-][a-zA-Z]+)*$")) { + // Returns the validated name if it meets the pattern requirements. + return name; + } else { + // Displays an error message if validation fails. + System.out.println("\nInvalid name. Please use letters only."); + } + } + } + + // Validates and formats the user’s phone number input using the provided pattern. + public static String formatPhoneNumber(Pattern pattern, Scanner sc) { + while (true) { + // Prompts the user to enter their phone number. + System.out.print("Enter a phone number: "); + String phoneNumber = sc.nextLine(); + + // Creates a Matcher object to compare input against the pattern. + Matcher matcher = pattern.matcher(phoneNumber); + + // Checks whether the phone number matches the expected format. + if (matcher.matches()) { + // Formats the number into XXX-XXX-XXXX structure. + return (matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3)); + } else { + // Displays an error message if validation fails. + System.out.println("\nInvalid phone number. Please try again.\n"); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/org/codedifferently/Main.java b/src/main/java/org/codedifferently/Main.java deleted file mode 100644 index 435139b..0000000 --- a/src/main/java/org/codedifferently/Main.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.codedifferently; - -//TIP To Run code, press or -// click the icon in the gutter. -public class Main { - public static void main(String[] args) { - //TIP Press with your caret at the highlighted text - // to see how IntelliJ IDEA suggests fixing it. - System.out.printf("Hello and welcome!"); - - for (int i = 1; i <= 5; i++) { - //TIP Press to start debugging your code. We have set one breakpoint - // for you, but you can always add more by pressing . - System.out.println("i = " + i); - } - } -} \ No newline at end of file