'', 'email' => '', 'phone' => '' ]; // Initialize display name variable $display_name = ''; // Initialize force form variable $forceShowForm = false; // ========== MINIMAL CHANGE: Check for pre-selected services from services.php ========== $preSelectedServiceIds = []; if (isset($_GET['selected_services'])) { $ids = explode(',', $_GET['selected_services']); $preSelectedServiceIds = array_filter(array_map('intval', $ids)); // Store in session for persistence $_SESSION['pre_selected_services'] = $preSelectedServiceIds; } // Also check if coming from services.php bookmark if (isset($_GET['book_appointment'])) { echo ''; } // ========== RESCHEDULE MODE DETECTION ========== $isRescheduleMode = false; $rescheduleAppointmentId = 0; $rescheduleAppointmentData = null; if (isset($_GET['reschedule']) && is_numeric($_GET['reschedule'])) { $rescheduleAppointmentId = intval($_GET['reschedule']); // Check if user is logged in if (isset($_SESSION['user_id'])) { $isRescheduleMode = true; // Fetch appointment details for rescheduling $reschedule_sql = " SELECT a.Appointment_ID, a.Appointment_Date, a.start_time, a.end_time, a.Appointment_Status, a.Dentist_ID, a.notes, d.name AS dentist_name, GROUP_CONCAT(aps.service_id) as service_ids, GROUP_CONCAT(s.service_name) as service_names FROM appointment a LEFT JOIN appointment_services aps ON a.Appointment_ID = aps.appointment_id LEFT JOIN services s ON aps.service_id = s.service_ID LEFT JOIN dentists d ON a.Dentist_ID = d.Dentist_ID WHERE a.Appointment_ID = ? AND a.Patient_ID = ? GROUP BY a.Appointment_ID "; $reschedule_stmt = $conn->prepare($reschedule_sql); $reschedule_stmt->bind_param("ii", $rescheduleAppointmentId, $_SESSION['user_id']); $reschedule_stmt->execute(); $reschedule_result = $reschedule_stmt->get_result(); if ($reschedule_result->num_rows > 0) { $rescheduleAppointmentData = $reschedule_result->fetch_assoc(); // Pre-select services for the form if (!empty($rescheduleAppointmentData['service_ids'])) { $reschedule_service_ids = explode(',', $rescheduleAppointmentData['service_ids']); $preSelectedServiceIds = array_merge($preSelectedServiceIds, $reschedule_service_ids); $_SESSION['pre_selected_services'] = $preSelectedServiceIds; } } else { // Appointment not found or doesn't belong to user $isRescheduleMode = false; $rescheduleAppointmentId = 0; } $reschedule_stmt->close(); } } // ========== BRACES-SPECIFIC: FUNCTIONS FOR PREVIOUS DENTIST DETECTION ========== // Original function for exact service matches (non-braces services) function getPreviousDentistForService($conn, $patient_id, $service_id) { $previousDentist = null; // FIRST: Check appointment_services table (for multi-service appointments) $sql = "SELECT aps.dentist_id as Dentist_ID, d.name AS dentist_name, a.Appointment_Date, GROUP_CONCAT(DISTINCT s.service_name) as service_names FROM appointment a INNER JOIN appointment_services aps ON a.Appointment_ID = aps.appointment_id INNER JOIN services s ON aps.service_id = s.service_ID INNER JOIN dentists d ON aps.dentist_id = d.Dentist_ID WHERE a.Patient_ID = ? AND aps.service_id = ? AND a.Appointment_Status IN ('Completed', 'Confirmed') AND aps.dentist_id IS NOT NULL GROUP BY a.Appointment_ID, aps.dentist_id ORDER BY a.Appointment_Date DESC, a.Appointment_ID DESC LIMIT 1"; $stmt = $conn->prepare($sql); $stmt->bind_param("ii", $patient_id, $service_id); $stmt->execute(); $result = $stmt->get_result(); if ($result->num_rows > 0) { $previousDentist = $result->fetch_assoc(); $stmt->close(); return $previousDentist; } $stmt->close(); // SECOND: If not found in appointment_services, check appointment.Service_ID (single service appointments) $sql2 = "SELECT a.Dentist_ID, d.name AS dentist_name, a.Appointment_Date, s.service_name as service_names FROM appointment a LEFT JOIN services s ON a.Service_ID = s.service_ID LEFT JOIN dentists d ON a.Dentist_ID = d.Dentist_ID WHERE a.Patient_ID = ? AND a.Service_ID = ? AND a.Appointment_Status IN ('Completed', 'Confirmed') AND a.Dentist_ID IS NOT NULL ORDER BY a.Appointment_Date DESC, a.Appointment_ID DESC LIMIT 1"; $stmt2 = $conn->prepare($sql2); $stmt2->bind_param("ii", $patient_id, $service_id); $stmt2->execute(); $result2 = $stmt2->get_result(); if ($result2->num_rows > 0) { $previousDentist = $result2->fetch_assoc(); } $stmt2->close(); return $previousDentist; } // NEW: Braces-specific function for detecting both placement and follow-ups function getDentistForBracesService($conn, $patient_id, $service_id) { $result = [ 'found' => false, 'dentist_id' => null, 'dentist_name' => null, 'last_appointment_date' => null, 'match_type' => null, // 'initial' or 'followup' 'service_type' => null, 'initial_date' => null ]; // Get the service name $currentServiceQuery = "SELECT service_name FROM services WHERE service_ID = ?"; $stmt = $conn->prepare($currentServiceQuery); $stmt->bind_param("i", $service_id); $stmt->execute(); $currentServiceResult = $stmt->get_result(); $currentService = $currentServiceResult->fetch_assoc(); $currentServiceName = strtolower($currentService['service_name'] ?? ''); $stmt->close(); // Check if this is a treatment-related service (braces, bridges, crowns, implants, dentures, tmj, veneers) $treatmentKeywords = [ 'brace', 'braces', 'orthodontic', 'ortho', 'bridge', 'crown', 'implant', 'denture', 'tmj', 'veneer', 'root canal' ]; $isTreatmentService = false; foreach ($treatmentKeywords as $keyword) { if (strpos($currentServiceName, $keyword) !== false) { $isTreatmentService = true; break; } } if (!$isTreatmentService) { return $result; // Not a treatment service } // Determine if this is likely initial placement or follow-up based on keywords $initialKeywords = ['placement', 'initial', 'install', 'new', 'start']; $followUpKeywords = ['adjust', 'adjustment', 'follow', 'follow-up', 'check', 'tighten', 'maintenance']; $isInitialService = false; $isFollowUpService = false; foreach ($initialKeywords as $keyword) { if (strpos($currentServiceName, $keyword) !== false) { $isInitialService = true; break; } } foreach ($followUpKeywords as $keyword) { if (strpos($currentServiceName, $keyword) !== false) { $isFollowUpService = true; break; } } // If no clear indicators, check patient history for THIS SPECIFIC SERVICE if (!$isInitialService && !$isFollowUpService) { // Look for any previous appointments with the EXACT SAME SERVICE $historySql = "SELECT COUNT(*) as count FROM appointment a WHERE a.Patient_ID = ? AND a.Service_ID = ? AND a.Appointment_Status IN ('Completed', 'Confirmed')"; $historyStmt = $conn->prepare($historySql); $historyStmt->bind_param("ii", $patient_id, $service_id); $historyStmt->execute(); $historyResult = $historyStmt->get_result(); $historyData = $historyResult->fetch_assoc(); $historyStmt->close(); if ($historyData['count'] > 0) { $isFollowUpService = true; // Patient has history with this service, treat as follow-up } else { $isInitialService = true; // No history with this service, treat as initial } } $result['service_type'] = $isInitialService ? 'initial' : 'followup'; // ========== CASE 1: INITIAL TREATMENT SERVICE (Placement/New Treatment) ========== if ($isInitialService) { // Look for previous appointments with the EXACT SAME SERVICE $sql = "SELECT a.Dentist_ID, d.name AS dentist_name, a.Appointment_Date, s.service_name FROM appointment a LEFT JOIN dentists d ON a.Dentist_ID = d.Dentist_ID LEFT JOIN services s ON a.Service_ID = s.service_ID WHERE a.Patient_ID = ? AND a.Service_ID = ? AND a.Appointment_Status IN ('Completed', 'Confirmed') AND a.Dentist_ID IS NOT NULL ORDER BY a.Appointment_Date DESC LIMIT 1"; $stmt = $conn->prepare($sql); $stmt->bind_param("ii", $patient_id, $service_id); $stmt->execute(); $treatmentResult = $stmt->get_result(); if ($treatmentResult->num_rows > 0) { $previous = $treatmentResult->fetch_assoc(); $result['found'] = true; $result['dentist_id'] = $previous['Dentist_ID']; $result['dentist_name'] = $previous['dentist_name']; $result['last_appointment_date'] = $previous['Appointment_Date']; $result['match_type'] = 'initial'; $result['initial_date'] = $previous['Appointment_Date']; } $stmt->close(); } // ========== CASE 2: FOLLOW-UP TREATMENT SERVICE (Adjustments) ========== if ($isFollowUpService) { // FIRST PRIORITY: Find the most recent INITIAL treatment placement for RELATED service // For follow-ups, look for the main treatment service (without 'Follow-Up' in name) // Get the base service name by removing follow-up indicators $baseServiceName = preg_replace('/\s*\([^)]*follow[^)]*\)/i', '', $currentServiceName); $baseServiceName = preg_replace('/\s*follow[- ]?up\s*/i', '', $baseServiceName); $baseServiceName = trim($baseServiceName); // Find the service ID of the main treatment (without follow-up) $mainServiceId = $service_id; // default to current ID $mainServiceSql = "SELECT service_ID FROM services WHERE LOWER(service_name) = LOWER(?) OR LOWER(service_name) LIKE CONCAT(LOWER(?), '%') AND LOWER(service_name) NOT LIKE '%follow%' LIMIT 1"; $mainServiceStmt = $conn->prepare($mainServiceSql); $mainServiceStmt->bind_param("ss", $baseServiceName, $baseServiceName); $mainServiceStmt->execute(); $mainServiceResult = $mainServiceStmt->get_result(); if ($mainServiceRow = $mainServiceResult->fetch_assoc()) { $mainServiceId = $mainServiceRow['service_ID']; } $mainServiceStmt->close(); // Now look for initial/main treatment with this service ID $initialSql = "SELECT a.Dentist_ID, d.name AS dentist_name, a.Appointment_Date, a.Appointment_ID FROM appointment a LEFT JOIN dentists d ON a.Dentist_ID = d.Dentist_ID LEFT JOIN services s ON a.Service_ID = s.service_ID WHERE a.Patient_ID = ? AND a.Service_ID = ? AND a.Appointment_Status IN ('Completed', 'Confirmed') AND a.Dentist_ID IS NOT NULL ORDER BY a.Appointment_Date ASC LIMIT 1"; $initialStmt = $conn->prepare($initialSql); $initialStmt->bind_param("ii", $patient_id, $mainServiceId); $initialStmt->execute(); $initialResult = $initialStmt->get_result(); if ($initialResult->num_rows > 0) { $initial = $initialResult->fetch_assoc(); $result['found'] = true; $result['dentist_id'] = $initial['Dentist_ID']; $result['dentist_name'] = $initial['dentist_name']; $result['last_appointment_date'] = $initial['Appointment_Date']; $result['match_type'] = 'followup'; $result['initial_date'] = $initial['Appointment_Date']; } $initialStmt->close(); // SECOND PRIORITY: If no initial placement found, look for most recent follow-up for SAME service if (!$result['found']) { $followUpSql = "SELECT a.Dentist_ID, d.name AS dentist_name, a.Appointment_Date FROM appointment a LEFT JOIN dentists d ON a.Dentist_ID = d.Dentist_ID LEFT JOIN services s ON a.Service_ID = s.service_ID WHERE a.Patient_ID = ? AND a.Service_ID = ? AND a.Appointment_Status IN ('Completed', 'Confirmed') AND a.Dentist_ID IS NOT NULL ORDER BY a.Appointment_Date DESC LIMIT 1"; $followUpStmt = $conn->prepare($followUpSql); $followUpStmt->bind_param("ii", $patient_id, $service_id); $followUpStmt->execute(); $followUpResult = $followUpStmt->get_result(); if ($followUpResult->num_rows > 0) { $previous = $followUpResult->fetch_assoc(); $result['found'] = true; $result['dentist_id'] = $previous['Dentist_ID']; $result['dentist_name'] = $previous['dentist_name']; $result['last_appointment_date'] = $previous['Appointment_Date']; $result['match_type'] = 'followup_previous'; } $followUpStmt->close(); } } return $result; } // ========== MAIN PREVIOUS DENTIST COLLECTION ========== $previousDentistsByService = []; // DEBUG: Add this to check user ID $debug_user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : 0; if (isset($_SESSION['user_id'])) { $user_id = $_SESSION['user_id']; // Connect to database $conn = new mysqli('localhost', 'root', '', 'clinic_db'); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // Fetch user info - UPDATED TO INCLUDE FIRST NAME $sql = "SELECT fullname, email, phone, first_name FROM users WHERE id = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("i", $user_id); $stmt->execute(); $result = $stmt->get_result(); if ($result && $result->num_rows > 0) { $userData = $result->fetch_assoc(); // Set display name (first name if available, otherwise username) $display_name = !empty($userData['first_name']) ? htmlspecialchars($userData['first_name']) : htmlspecialchars($_SESSION['username']); } else { // Fallback to username if user not found $display_name = isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : ''; } $stmt->close(); // Check if user has already submitted patient form $sql2 = "SELECT COUNT(*) FROM patient_records WHERE user_id = ?"; $stmt2 = $conn->prepare($sql2); $stmt2->bind_param("i", $user_id); $stmt2->execute(); $stmt2->bind_result($count); $stmt2->fetch(); $stmt2->close(); // If no records, force show form if ($count == 0) { $forceShowForm = true; } // Get all active services $allServicesQuery = "SELECT service_ID, service_name FROM services WHERE is_active = 1 ORDER BY service_ID"; $allServicesResult = mysqli_query($conn, $allServicesQuery); $serviceCount = 0; $servicesWithPreviousDentist = 0; while ($service = mysqli_fetch_assoc($allServicesResult)) { $service_id = $service['service_ID']; $service_name = $service['service_name']; $serviceCount++; // Check if this is a treatment-related service (braces, bridges, crowns, implants, dentures, tmj, veneers) $treatmentKeywords = [ 'brace', 'braces', 'orthodontic', 'ortho', 'bridge', 'crown', 'implant', 'denture', 'tmj', 'veneer', 'root canal' ]; $isTreatmentService = false; foreach ($treatmentKeywords as $keyword) { if (stripos($service_name, $keyword) !== false) { $isTreatmentService = true; break; } } if ($isTreatmentService) { // Use treatment-specific function $dentistData = getDentistForBracesService($conn, $user_id, $service_id); if ($dentistData['found']) { $servicesWithPreviousDentist++; $previousDentistsByService[$service_id] = [ 'dentist_id' => $dentistData['dentist_id'], 'dentist_name' => $dentistData['dentist_name'], 'last_appointment_date' => $dentistData['last_appointment_date'], 'match_type' => $dentistData['match_type'], 'service_type' => $dentistData['service_type'], 'initial_date' => $dentistData['initial_date'] ]; } } else { // For non-treatment services, use original exact match logic $previousDentist = getPreviousDentistForService($conn, $user_id, $service_id); if ($previousDentist) { $servicesWithPreviousDentist++; $previousDentistsByService[$service_id] = [ 'dentist_id' => $previousDentist['Dentist_ID'], 'dentist_name' => $previousDentist['dentist_name'], 'last_appointment_date' => $previousDentist['Appointment_Date'], 'service_names' => $previousDentist['service_names'], 'match_type' => 'exact' ]; } } } $conn->close(); } // Convert to JSON for JavaScript use $previousDentistsJson = json_encode($previousDentistsByService); // DEBUG: Add visible debug output (will appear as HTML comments) echo ""; echo ""; echo ""; echo ""; echo ""; ?> Umipig Dental Clinic
'', 'email' => '', 'phone' => '' ]; // Initialize force form variable $forceShowForm = false; // Initialize display name variable for header $header_display_name = ''; if (isset($_SESSION['user_id'])) { $user_id = $_SESSION['user_id']; // Connect to database $conn = new mysqli('localhost', 'root', '', 'clinic_db'); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // Fetch user info - UPDATED TO INCLUDE FIRST NAME $sql = "SELECT fullname, email, phone, first_name FROM users WHERE id = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("i", $user_id); $stmt->execute(); $result = $stmt->get_result(); if ($result && $result->num_rows > 0) { $userData = $result->fetch_assoc(); // Set display name for header (first name if available, otherwise username) $header_display_name = !empty($userData['first_name']) ? htmlspecialchars($userData['first_name']) : (isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : ''); } $stmt->close(); // Check if user has already submitted patient form $sql2 = "SELECT COUNT(*) FROM patient_records WHERE user_id = ?"; $stmt2 = $conn->prepare($sql2); $stmt2->bind_param("i", $user_id); $stmt2->execute(); $stmt2->bind_result($count); $stmt2->fetch(); $stmt2->close(); // If no records, force show form if ($count == 0) { $forceShowForm = true; } } require_once 'clinic_functions.php'; $clinic_info = getClinicInformation($conn); // Prepare clinic hours for JavaScript $clinic_hours_js = []; $days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; foreach ($days as $day) { $hours = $clinic_info['clinic_hours'][$day] ?? ['open' => '09:00', 'close' => '17:00', 'closed' => false]; $clinic_hours_js[$day] = [ 'open' => $hours['open'], 'close' => $hours['close'], 'closed' => $hours['closed'] ]; } ?>
<?php echo htmlspecialchars($clinic_info['clinic_name'] ?? 'Umipig Dental Clinic'); ?>

Welcome, prepare("SELECT first_name FROM users WHERE id = ?"); $name_stmt->bind_param("i", $_SESSION['user_id']); $name_stmt->execute(); $name_result = $name_stmt->get_result(); if ($name_row = $name_result->fetch_assoc()) { if (!empty($name_row['first_name'])) { $first_name_display = $name_row['first_name']; } } $name_stmt->close(); } // Fallback to username if first name not found if (empty($first_name_display)) { $first_name_display = $_SESSION['username']; } echo htmlspecialchars($first_name_display); ?>!    |  Logout Register | Login

About Our Clinic

Our Mission

At Umipig Dental Clinic, our mission is to deliver compassionate, high-quality dental care that enhances the health and confidence of every patient we serve. We are dedicated to creating a welcoming and comfortable environment where patients of all ages feel safe and cared for. Our team of skilled professionals is committed to staying updated with the latest advancements in dental technology and treatment methods to ensure optimal care. We believe in educating our patients, empowering them to make informed decisions about their oral health. Integrity, professionalism, and genuine concern for our patients are at the heart of everything we do. We strive to build long-lasting relationships based on trust, respect, and outstanding results. Through our commitment to excellence, we aim to transform smiles and improve lives—one patient at a time.

Our Values

  • Patient-Centered Care
  • Professional Excellence
  • Continuous Education
  • Gentle Approach

Why Choose Us?

🦷

Modern Equipment

State-of-the-art dental technology for precise treatment

👨‍⚕️

Expert Team

Experienced dentists and friendly staff

🏥

Clean Environment

Sterile and comfortable clinic setting

💰

Affordable Care

Competitive pricing and flexible payment options

Treatment Results

Before Treatment After Treatment

Orthodontic Treatment

Before Treatment After Treatment

Veneers

Reschedule Appointment

You are rescheduling an existing appointment

Original: at with

Schedule Your Visit

0): ?>
Select up to 3 services Click to choose services
"; } // Update the dropdown label if services are pre-selected if (!empty($selectedServiceNames)) { $initialLabel = implode(' • ', array_slice($selectedServiceNames, 0, 3)); if (count($selectedServiceNames) > 3) { $initialLabel .= ' (and ' . (count($selectedServiceNames) - 3) . ' more)'; } echo ""; } ?>

Estimated Duration: —

Available Time Slots

Attach Dental Records (Optional)

Max file size: 10MB per file
Allowed: PDF, Images, Documents
Upload dental X-rays, previous records, or consent forms for better service.

Additional Remarks (Optional)

Share any additional information that might help us provide better service

Clinic Hours

    '09:00', 'close' => '17:00', 'closed' => false]; $is_closed = $hours['closed'] ?? false; if ($is_closed): ?>
  • : Closed
  • : -

For emergencies, don't hesitate to text/call

Dentists' Availabilities

query($sql); if ($result && $result->num_rows > 0) { while ($row = $result->fetch_assoc()) { $dentistID = $row['Dentist_ID']; $name = htmlspecialchars($row['name']); $specialization = htmlspecialchars($row['specialization']); // Get availability for the next 35 days to match the Select Date field $availabilitySql = "SELECT da.available_date, da.available_time, da.day_of_week, da.end_time FROM dentistavailability da INNER JOIN dentists d ON da.Dentist_ID = d.Dentist_ID WHERE da.Dentist_ID = $dentistID AND d.is_active = 1 AND d.deleted_at IS NULL AND da.available_date >= CURDATE() AND da.available_date <= DATE_ADD(CURDATE(), INTERVAL 35 DAY) ORDER BY da.available_date, da.available_time LIMIT 200"; $availabilityResult = $conn->query($availabilitySql); $nextAvailableDate = ''; $availableSlots = []; $currentDate = ''; $availability_by_date = []; // Group availability by date if ($availabilityResult && $availabilityResult->num_rows > 0) { while ($avail = $availabilityResult->fetch_assoc()) { $date = $avail['available_date']; $start_time = $avail['available_time']; // Use end_time if available, otherwise calculate it (30 minutes) if (!empty($avail['end_time']) && $avail['end_time'] != '00:00:00') { $end_time = $avail['end_time']; } else { $end_time = date('H:i:s', strtotime($start_time . ' +30 minutes')); } if (!isset($availability_by_date[$date])) { $availability_by_date[$date] = []; } $availability_by_date[$date][] = [ 'start' => $start_time, 'end' => $end_time ]; // Set first available date if (empty($currentDate)) { $currentDate = $date; $nextAvailableDate = date('D, M j', strtotime($currentDate)); } } } // ========== FIXED: USE DENTIST'S ACTUAL AVAILABILITY, NOT CLINIC HOURS ========== if (!empty($currentDate)) { $currentDayOfWeek = date('l', strtotime($currentDate)); // Check if clinic is open on this day $dayHours = $clinic_hours[$currentDayOfWeek] ?? ['open' => '09:00', 'close' => '17:00', 'closed' => false]; if ($dayHours['closed']) { // Clinic is closed, no availability $availableSlots = []; } else { // Get dentist's availability for this specific date $dentist_slots = $availability_by_date[$currentDate] ?? []; if (empty($dentist_slots)) { // No specific availability for this date $availableSlots = []; } else { // Generate time slots based on dentist's actual availability ranges $all_slots = []; foreach ($dentist_slots as $slot) { $slot_start = strtotime($slot['start']); $slot_end = strtotime($slot['end']); // Ensure within clinic hours $clinic_open = strtotime($dayHours['open']); $clinic_close = strtotime($dayHours['close']); $slot_start = max($slot_start, $clinic_open); $slot_end = min($slot_end, $clinic_close); if ($slot_start < $slot_end) { // Generate 30-minute slots within this availability range $current_slot = $slot_start; while ($current_slot < $slot_end) { $slotTime = date('H:i', $current_slot); $all_slots[] = $slotTime; $current_slot += 1800; // 30 minutes } } } $availableSlots = array_unique($all_slots); sort($availableSlots); } } } // ========== END FIXED SECTION ========== // Get booked slots for the current date $bookedSlots = []; if (!empty($currentDate)) { $bookedSql = "SELECT start_time, end_time FROM appointment WHERE Dentist_ID = $dentistID AND Appointment_Date = '$currentDate' AND Appointment_Status IN ('Pending', 'Confirmed', 'Rescheduled')"; $bookedResult = $conn->query($bookedSql); if ($bookedResult && $bookedResult->num_rows > 0) { while ($bookedRow = $bookedResult->fetch_assoc()) { $start = strtotime($bookedRow['start_time']); $end = strtotime($bookedRow['end_time']); // Mark all 30-minute intervals that overlap with the appointment for ($time = $start; $time < $end; $time += 900) { // Check every 15 minutes $slotTime = date('H:i', $time); // Convert to nearest 30-minute slot $hour = date('H', $time); $minute = floor(date('i', $time) / 30) * 30; $thirtyMinSlot = sprintf('%02d:%02d', $hour, $minute); $bookedSlots[] = $thirtyMinSlot; } } } $bookedSlots = array_unique($bookedSlots); } $slotsAvailable = !empty(array_diff($availableSlots, $bookedSlots)); echo '

' . $name . '

' . formatSpecialization($specialization) . '
'; if (!empty($nextAvailableDate)) { echo '
Next Available: ' . $nextAvailableDate . '
'; // Generate date options - only show dates where dentist has availability foreach ($nextDates as $date => $display) { $hasAvailability = isset($availability_by_date[$date]) && !empty($availability_by_date[$date]); $dayOfWeek = date('l', strtotime($date)); $clinicOpen = !($clinic_hours[$dayOfWeek]['closed'] ?? false); if ($hasAvailability && $clinicOpen) { $selected = $date === $currentDate ? 'selected' : ''; echo '
' . $display . '
'; } } echo '
Time Slots Status ' . ($slotsAvailable ? 'Available' : 'Fully Booked') . '
'; if (!empty($availableSlots)) { foreach ($availableSlots as $slotTime) { $formattedTime = date('h:i A', strtotime($slotTime)); $isBooked = in_array($slotTime, $bookedSlots); $cssClass = $isBooked ? 'time-slot booked' : 'time-slot available'; echo '
' . $formattedTime . '
'; } } else { $dayOfWeek = date('l', strtotime($currentDate)); $isClosed = $clinic_hours[$dayOfWeek]['closed'] ?? false; if ($isClosed) { echo '
Clinic Closed
'; } else { echo '
No time slots available
'; } } echo '
'; } else { echo '
Currently fully booked New slots may open soon
'; } echo '
'; } } else { echo '

No dentists available at the moment.

'; } $conn->close(); function formatSpecialization($text) { $items = explode(',', $text); $formatted = '
    '; foreach ($items as $item) { $formatted .= '
  • ' . trim($item) . '
  • '; } $formatted .= '
'; return $formatted; } ?>

Check back regularly for schedule updates.

Call Us Directly

Speak directly with our staff during clinic hours for immediate assistance.

Email Us

Send us an email and we'll respond within 24 hours during business days.

Message on Facebook

Connect with us on Facebook for quick answers to your questions.