Header Ads

Header ADS

Laravel Chatgpt implementation for Doctor appointment

//AppointmentController.php code

    public function check(Request $request)
    {


        $request->validate([
            'user_id' => 'required|integer|exists:users,id',
            'service_id' => 'required|integer|exists:services,id',
            'admin_id' => 'required|integer|exists:admins,id',
            'appointment_date' => 'required|date'
        ]);

   

        $doctor = Admin::where('id', $request->admin_id)
            ->whereHas('role', fn($q) => $q->where('name', 'Doctor'))
            ->firstOrFail();

        $service = Service::findOrFail($request->service_id);

        $date = $request->appointment_date;
        $dayOfWeek = date('l', strtotime($date));

        $schedule = DoctorSchedule::where('admin_id', $doctor->id)
            ->whereHas('day', fn($q) => $q->where('name', $dayOfWeek))
            ->first();

        $scheduleText = $schedule
            ? "{$schedule->day_id}: {$schedule->start_time} - {$schedule->end_time}"
            : "Doctor not available on {$dayOfWeek}";

        $prompt = "A patient named {$request->name} wants to book a {$service->title} with Dr. {$doctor->name} on {$date}.
    The doctor's schedule for {$dayOfWeek} is {$scheduleText}.
    Suggest 2-3 available appointment time slots during working hours.
    If the doctor is unavailable on that day, suggest the next available day.";

        $apiKey = gs()->open_ai_key;

        $payload = [
            'model' => 'gpt-4o-mini',
            'messages' => [
                ['role' => 'system', 'content' => 'You are an AI scheduling assistant for a dental clinic.'],
                ['role' => 'user', 'content' => $prompt],
            ],
            'temperature' => 0.5,
        ];

        $response = Http::withHeaders([
            'Authorization' => 'Bearer ' . $apiKey,
            'Content-Type' => 'application/json',
        ])->post('https://api.openai.com/v1/chat/completions', $payload);

        $data = $response->json();
        $aiMessage = $data['choices'][0]['message']['content'] ?? 'No suggestion generated.';

        return response()->json([
            'success' => true,
            'ai_message' => nl2br(e($aiMessage)),
        ]);
    }


    public function book(Request $request)
    {

        $request->validate([
            'user_id' => 'required|integer|exists:users,id',
            'service_id' => 'required|integer|exists:services,id',
            'admin_id' => 'required|integer|exists:admins,id',
            'doctor_schedule_id' => 'required|integer|exists:doctor_schedules,id',
            'appointment_date' => 'required|date'
        ]);

        $appointment = new Appointment();
        $appointment->user_id = $request->user_id;
        $appointment->service_id = $request->service_id;
        $appointment->admin_id = $request->admin_id;
        $appointment->appointment_date = $request->appointment_date;
        $appointment->doctor_schedule_id = $request->doctor_schedule_id;
        $appointment->save();

        $user = User::find($request->user_id);
        $userNotification = new UserNotification();
        $userNotification->user_id   = $user->id;
        $userNotification->title     = 'Appointment Booked Successfully';
        $userNotification->click_url = urlPath('user.appointment.details', $appointment->id);
        $userNotification->save();

        return response()->json([
            'success' => true,
            'message' => 'Appointment booked successfully!',
        ]);
    }

//appointment.blade.php code

@extends($activeTemplate . 'layouts.frontend')
@section('content')


    @php
        $appointmentContent = getContent('appointment.content', true);
        $services = \App\Models\Service::where('status', 1)->get();
        $doctors = \App\Models\Admin::whereHas('role', function ($q) {
            $q->where('name', 'Doctor');
        })->get();

        use App\Models\DoctorSchedule;

        $openingHours = DoctorSchedule::with('day')
            ->select('day_id', 'start_time', 'end_time')
            ->distinct('day_id')
            ->where('status', 1)
            ->get()
            ->sortBy(function ($schedule) {
                $customOrder = [
                    'Sunday' => 1,
                    'Monday' => 2,
                    'Tuesday' => 3,
                    'Wednesday' => 4,
                    'Thursday' => 5,
                    'Friday' => 6,
                    'Saturday' => 7,
                ];

                return $customOrder[$schedule->day->name] ?? 8;
            });

        $doctorSchedules = \App\Models\DoctorSchedule::with('day')
            ->select('id', 'day_id', 'start_time', 'end_time')
            ->distinct('day_id')
            ->orderBy('day_id')
            ->get();
    @endphp

    <section class="booking mt-120">
        <div class="container">
            <div class="booking__wrapper">
                <div class="row">
                    <div class="col-lg-12">
                        <div class="booking__wrap">
                            <div class="opening__hours bg--img"
                                data-background-image="{{ asset($activeTemplateTrue . 'images/our-services-shape.png') }}">
                                <h4 class="opening__hours-title">{{ __($appointmentContent->data_values->hours_heading) }}
                                </h4>

                                @foreach ($openingHours as $schedule)
                                    <div class="opening__hours-wrap">
                                        <span>{{ $schedule->day->name ?? '' }}:</span>
                                        <p>
                                            {{ \Carbon\Carbon::createFromFormat('H:i:s', $schedule->start_time)->format('h:i A') }}
                                            -
                                            {{ \Carbon\Carbon::createFromFormat('H:i:s', $schedule->end_time)->format('h:i A') }}
                                        </p>
                                    </div>
                                @endforeach
                            </div>

                            <div class="appointment">
                                <h3 class="appointment__title">{{ __($appointmentContent->data_values->book_heading) }}</h3>

                                <form id="appointmentForm">
                                    @csrf
                                    <input type="hidden" name="user_id" value="{{ auth()->id() }}">

                                    <div class="auth__form">
                                        <input type="text" name="name" class="form-control"
                                            value="{{ auth()->user()->firstname ?? '' }}" placeholder="@lang('Your Name')"
                                            required>
                                    </div>

                                    <div class="auth__form">
                                        <input type="text" name="phone" class="form-control"
                                            value="{{ auth()->user()->mobile ?? '' }}" placeholder="@lang('Your Number')"
                                            required>
                                    </div>

                                    <div class="auth__form">
                                        <input type="email" name="email" class="form-control"
                                            value="{{ auth()->user()->email ?? '' }}" placeholder="@lang('Your Email')"
                                            required>
                                    </div>

                                    <div class="auth__form">
                                        <select class="form-select" name="service_id" required>
                                            <option value="" selected disabled>@lang('Type Of Service')</option>
                                            @foreach ($services as $service)
                                                <option value="{{ $service->id }}">{{ __($service->title) }}</option>
                                            @endforeach
                                        </select>
                                    </div>

                                    <div class="auth__form">
                                        <select class="form-select" name="admin_id" required>
                                            <option value="" selected>@lang('Doctor')</option>
                                            @foreach ($doctors as $doctor)
                                                <option value="{{ $doctor->id }}">{{ __($doctor->name) }}</option>
                                            @endforeach
                                        </select>
                                    </div>

                                    <div class="auth__form">
                                        <input type="date" name="appointment_date" id="appointment_date"
                                            class="form-control" required>
                                    </div>

                                    <div class="auth__form">
                                        <select class="form-select" name="doctor_schedule_id" required>
                                            <option value="" selected>@lang('Select Time Slot')</option>
                                            @foreach ($doctorSchedules as $schedule)
                                                <option value="{{ $schedule->id }}">
                                                    {{ \Carbon\Carbon::createFromFormat('H:i:s', $schedule->start_time)->format('h:i A') }}
                                                    @lang('to')
                                                    {{ \Carbon\Carbon::createFromFormat('H:i:s', $schedule->end_time)->format('h:i A') }}
                                                </option>
                                            @endforeach
                                        </select>
                                    </div>
                                    <div class="booking__button d-flex gap-2">
                                        <button type="button" id="checkBtn" class="btn btn--base-two"
                                            disabled>@lang('Check Availability')</button>
                                        <button type="button" id="bookBtn" class="btn btn--success"
                                            style="display:none;">@lang('Book an  Appointment')</button>
                                    </div>
                                </form>
                                <div id="aiSuggestionBox" class="ai_suggestionbox" style="display:none;">
                                    <strong>@lang('Suggested Time Slots')</strong>
                                    <div id="aiResponse"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>


    @if ($sections->secs != null)
        @foreach (json_decode($sections->secs) as $sec)
            @include($activeTemplate . 'sections.' . $sec)
        @endforeach
    @endif
@endsection


@push('style')
    <style>
        .ai_suggestionbox {
            margin-top: 15px;
            display: none;
            border: 1px solid #ddd;
            padding: 10px;
            border-radius: 5px;
            color: #fff;
        }
    </style>
@endpush


@push('script')
    <script>
        (function($) {
            "use strict";

            $(document).ready(function() {
                const $form = $('#appointmentForm');
                const $checkBtn = $('#checkBtn');
                const $bookBtn = $('#bookBtn');

                const $requiredInputs = $form.find('[required]').not('[type="hidden"]');

                function checkFormValidity() {
                    let allValid = true;
                    $requiredInputs.each(function() {
                        if (!$(this).val() || $(this).val().trim() === '') {
                            allValid = false;
                            return false;
                        }
                    });

                    $checkBtn.prop('disabled', !allValid);
                    if (!allValid) {
                        $bookBtn.hide();
                        $('#aiSuggestionBox').hide();
                    }
                }

                $requiredInputs.on('input change', checkFormValidity);
                checkFormValidity();


                $('#checkBtn').on('click', function(e) {
                    e.preventDefault();

                    if ($checkBtn.prop('disabled')) {
                        return;
                    }

                    let formData = $form.serialize();

                    $.ajax({
                        url: "{{ route('appointment.check') }}",
                        method: "POST",
                        data: formData,
                        beforeSend: function() {
                            $('#aiResponse').html('Checking availability...');
                            $('#aiSuggestionBox').show();
                            $bookBtn.hide();
                        },
                        success: function(response) {
                            $('#aiResponse').html(response.ai_message);
                            $bookBtn.show();
                        },

                        error: function() {
                            $('#aiResponse').html('Error: Could not check availability.');
                            $bookBtn.hide();
                        }
                    });
                });


                $('#bookBtn').on('click', function(e) {
                    e.preventDefault();
                    let formData = $form.serialize();

                    $.ajax({
                        url: "{{ route('appointment.book') }}",
                        method: "POST",
                        data: formData,
                        beforeSend: function() {
                            $bookBtn.text('Booking...');
                        },
                        success: function(response) {
                            $bookBtn.text('Book an Appointment');
                            if (response.success) {
                                notify('success', 'Appointmented Successfully');
                                $bookBtn.hide();
                                $checkBtn.prop('disabled',
                                    true);
                                $('#aiResponse').append(
                                    '<br><strong> Appointment Confirmed!</strong>');
                            }
                        },
                        error: function() {
                            $bookBtn.text('Book an Appointment');
                            notify('error', 'Error: Could not book appointment.');
                        }
                    });
                });

            });

            // previous date disable
            const dateInput = document.getElementById('appointment_date');
            const today = new Date().toISOString().split('T')[0];
            dateInput.min = today;
        })(jQuery);
    </script>
@endpush


No comments

Theme images by fpm. Powered by Blogger.