PHP Laravel randevu sistemi istenilen şekilde çalışmıyor

koese

Decapat
Katılım
3 Kasım 2022
Mesajlar
18
Çözümler
1
Daha fazla  
Sistem Özellikleri
işlemci: i3 10110U
Ram: 20GB
ekran kartı: intel graphics
Cinsiyet
Erkek
Meslek
Bilgisayar Mühendisi
Öncelikle merhaba PHP Laravel ile bir randevu sistemi oluşturdum ancak istediğim gibi çalışmıyor. İstediğim şey tarih seçiliğinde önceden randevu alınmış ise bir saate saati seçilemez olarak göstermesi ve o gün tüm randevular alındı ise o günü kapatması ancak ne yaptıysam olmadı. Yardımcı olabilecek birisi olursa kodları paylaşacağım.
 
Kodu paylaşır mısın ? Ayrıca gpt'e sordun mu ?
 
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Randevu;
use Illuminate\Support\Carbon;
use App\Mail\RandevuOzelMaili;
use App\Mail\RandevuDurumGuncellemeMaili;
use App\Mail\RandevuTamamlandiMaili;
use Illuminate\Support\Facades\Mail; // Mail sınıfını dahil ettik

class RandevuController extends Controller
{
public function index(Request $request)
{
// Veritabanındaki tüm randevuları al
$randevular = Randevu::eek:rderBy('created_at', 'desc')->get();

// Kategoriler için harita
$categoryMap = [
'muayene' => 'Muayene',
'kanal_tedavisi' => 'Kanal Tedavisi',
'dis_cekimi' => 'Diş Çekimi',
'dolgu' => 'Dolgu',
'dis_tasi_temizligi' => 'Diş Taşı Temizliği',
'ortodonti' => 'Ortodonti',
'implant' => 'İmplant',
'dis_beyazlatma' => 'Diş Beyazlatma',
'protez' => 'Protez',
'roentgen' => 'Röntgen',
'pedodonti' => 'Pedodonti'
];

// Eğer AJAX isteği yapılıyorsa, JSON formatında döndürüyoruz
if ($request->ajax()) {
return response()->json([
'randevular' => $randevular // Sayfalama ile gelen randevular
]);
}

// Veriyi view'a gönder
return view('admin.randevular.randevu_liste', compact('randevular', 'categoryMap')); // compact() ile veri gönderiliyor
}

// Yeni randevu eklemek için
public function store(Request $request)
{
// Form verilerini doğrulama
$validated = $request->validate([
'full_name' => 'required|string|max:255',
'phone_number' => 'required|string|max:20',
'email' => 'required|email', // E-posta alanını ekliyoruz
'appointment_date' => 'required|date|after_or_equal:today',
'appointment_time' => 'required|date_format:H:i',
'category' => 'required|string', // Kategori kontrolü
'message' => 'nullable|string',
]);

// Aynı tarih ve saatte başka bir randevu olup olmadığını kontrol et
$existingAppointment = Randevu::where('appointment_date', $validated['appointment_date'])
->where('appointment_time', $validated['appointment_time'])
->first();

if ($existingAppointment) {
return redirect()->back()->with('danger', 'Geçerli saatte zaten bir randevu alınmış. Lütfen başka bir saat seçin.');
}

// Randevu oluşturma
$appointment = Randevu::create([
'full_name' => $validated['full_name'],
'phone_number' => $validated['phone_number'],
'email' => $validated['email'],
'appointment_date' => $validated['appointment_date'],
'appointment_time' => $validated['appointment_time'],
'category' => $validated['category'], // Kategori ekliyoruz
'status' => 'pending', // Varsayılan durum
'message' => $validated['message'],
]);

// Randevu bilgilerini e-posta için hazırlıyoruz
$appointmentDetails = [
'full_name' => $appointment->full_name,
'appointment_date' => $appointment->appointment_date,
'appointment_time' => $appointment->appointment_time,
'category' => $appointment->category
];

// Kullanıcıya randevu onayı e-postası gönderme
Mail::to($validated['email'])->send(new RandevuOzelMaili($appointmentDetails));

session()->put('new_appointment', 'Yeni bir randevunuz var!');

return redirect()->back()->with('success', 'Randevu Başarı ile oluşturuldu!');
}

// Randevuyu iptal etme
public function cancel($id)
{
// İlgili randevuyu bul
$appointment = Randevu::findOrFail($id);

// Randevu durumunu 'canceled' olarak güncelle
$appointment->update(['status' => 'canceled']);

// İptal mesajı döndür
return response()->json(['message' => 'Randevu iptal edildi']);
}

public function updateStatus(Request $request, $id)
{
$randevu = Randevu::findOrFail($id);

// Durum güncellemeyi kontrol et
$randevu->status = $request->input('status');
$randevu->save();

// Kategori ve durum çevirileri
$categoryMap = [
'muayene' => 'Muayene',
'kanal_tedavisi' => 'Kanal Tedavisi',
'dis_cekimi' => 'Diş Çekimi',
'dolgu' => 'Dolgu',
'dis_tasi_temizligi' => 'Diş Taşı Temizliği',
'ortodonti' => 'Ortodonti',
'implant' => 'İmplant',
'dis_beyazlatma' => 'Diş Beyazlatma',
'protez' => 'Protez',
'roentgen' => 'Röntgen',
'pedodonti' => 'Pedodonti'
];

$statusMap = [
'pending' => 'Beklemede',
'confirmed' => 'Onaylı',
'completed' => 'Tamamlandı',
'canceled' => 'İptal Edildi'
];

// Randevu bilgilerini e-posta için hazırlıyoruz (map'lenmiş haliyle)
$appointmentDetails = [
'full_name' => $randevu->full_name,
'appointment_date' => $randevu->appointment_date,
'appointment_time' => $randevu->appointment_time,
'category' => $categoryMap[$randevu->category] ?? $randevu->category,
'status' => $statusMap[$randevu->status] ?? $randevu->status,
];

// Kullanıcıya randevu durumu güncelleme e-postası gönderme
if ($randevu->status === 'completed') {
Mail::to($randevu->email)->send(new RandevuTamamlandiMaili($appointmentDetails));
} else {
Mail::to($randevu->email)->send(new RandevuDurumGuncellemeMaili($appointmentDetails));
}

return redirect()->back()->with('success', 'Randevu başarıyla güncellendi ve e-posta gönderildi.');
}



public function delete($id, Request $request)
{
// Randevuyu ID'ye göre bul
$randevu = Randevu::findOrFail($id);

// Randevuyu sil
$randevu->delete();

// AJAX ile gelen silme isteği ise JSON formatında yanıt gönderiyoruz
if ($request->ajax()) {
return response()->json([
'message' => 'Randevu başarıyla silindi.'
]);
}

return redirect()->back()->with('success', 'Randevu başarıyla silindi.');
}

public function checkAppointmentTimes(Request $request)
{
$date = $request->input('date'); // Seçilen tarih
$category = $request->input('category'); // Seçilen kategori

// Aynı tarih ve saatte tüm kategorilerde alınmış randevuları getir
$appointments = Randevu::where('appointment_date', $date)->get();

// Eğer o gün doluysa, o günü seçilemez yapalım
$bookedTimes = [];
$allDayBooked = false;

// Eğer o günün tamamı dolmuşsa, allDayBooked'ı true yapıyoruz
if ($appointments->count() >= 9 * 60) { // 9:00 - 18:00 arasında 9 saat x 60 dakika = 540 dakika
$allDayBooked = true;
}

// Dolu saatleri saklamak için bir dizi oluşturuyoruz
foreach ($appointments as $appointment) {
$bookedTimes[] = $appointment->appointment_time;
}

// Dolu saatler ve o günün tamamının dolu olduğu bilgisini JSON formatında döndürüyoruz
return response()->json([
'bookedTimes' => $bookedTimes,
'allDayBooked' => $allDayBooked
]);
}






}

BU CONTROLLER*******

*************************************************************-BUDA BLADE DOSYASI***********************************************************************
@extends('frontend.main_master')

@section('main')

<style type="text/css">
#appointment_time {
display: block;
width: 100%;
height: auto;
}
</style>


<!--Breadcrumb alanı başlangıç-->
<section class="breadcrumb-area" style="background-image: url('{{ asset('frontend/assets/images/resources/breadcrumb-bg.jpg') }}');">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="left pull-left">
<div class="title">
<h1>Randevu</h1>
</div>
</div>
<div class="right pull-right">
<ul>
<li><i class="fa fa-home home" aria-hidden="true"></i><a href="{{url('/')}}">Anasayfa</a></li>
<li><i class="fa fa-angle-right" aria-hidden="true"></i></li>
<li class="active">Randevu</li>
</ul>
</div>
</div>
</div>
</div>
</section>
<!--Breadcrumb alanı bitiş-->

<!--Randevu alanı başlangıç-->
<section class="appointment-page">
<div class="container">
<div class="sec-title text-center">
<h1>Randevu Oluştur</h1>
<span class="border"></span>
<div class="text-box">
<p>Aşağıdaki formu kullanarak kolayca randevu oluşturabilirsiniz.</br> Hizmet kategorisini seçtiğinizde, o kategoriye özel uygun saat aralıkları otomatik olarak listelenecektir.</p>
</div>
</div>
<div class="row">
<div class="appointment-box">
<div class="col-md-12">
<div class="form">
<form id="randevuForm" method="POST" action="{{ route('randevu.store') }}">
@csrf
<div class="row">
<div class="col-md-4">
<div class="input-box">
<label>Tam Adınız</label>
<input type="text" name="full_name" placeholder="Tam Adınız" required>
</div>
</div>
<div class="col-md-4">
<div class="input-box">
<label>Telefon Numaranız</label>
<input type="text" name="phone_number" value="" placeholder="Telefon Numaranız" required="">
</div>
</div>
<div class="col-md-4">
<div class="input-box">
<label>E-posta Adresiniz</label>
<input type="email" name="email" value="" placeholder="E-posta Adresiniz" required="">
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="input-box">
<label>Tarih Seçin</label>
<input style="height: 50px;border-radius: 0;border-color: #f5f5f5fa;" class="form-control" type="date" name="appointment_date" id="appointment_date" required min="{{ \Carbon\Carbon::today()->toDateString() }}">
</div>
</div>
<div class="col-md-4">
<div class="input-box">
<label id="category_label">Kategori Seçin</label>
<select class="form-control" id="category" name="category" required style="height: 50px;border-radius: 0;border-color: #f5f5f5fa;">
<option value="muayene">Muayene</option>
<option value="kanal_tedavisi">Kanal Tedavisi</option>
<option value="dis_cekimi">Diş Çekimi</option>
<option value="dolgu">Dolgu</option>
<option value="dis_tasi_temizligi">Diş Taşı Temizliği</option>
<option value="ortodonti">Ortodonti</option>
<option value="implant">İmplant</option>
<option value="dis_beyazlatma">Diş Beyazlatma</option>
<option value="protez">Protez Diş</option>
<option value="roentgen">Panoramik Röntgen</option>
<option value="pedodonti">Çocuk Diş Hekimliği</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="input-box">
<label>Randevu Saati Seçin</label>
<select style="height: 50px; border-radius: 0; border-color: #f5f5f5fa;" class="form-control" id="appointment_time" name="appointment_time" required>
<!-- Saatler burada dinamik olarak yüklenecek -->
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12" style="max-height: 100%;margin-top: 50px;">
<label>Mesajınız</label>
<textarea style="height: 150px" name="message" placeholder="(Dilerseniz bu alanı boş bırakabilirsiniz!)"></textarea>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="thm-btn bg-1" type="submit">Randevu Oluştur</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
<!--Randevu alanı bitiş-->


<!--Bülten alanı başlangıç-->
<section class="newsletter-area" style="background-image:url('{{ asset('frontend/assets/images/resources/newsletter-bg.jpg') }}');">
<div class="container">
<div class="sec-title center text-center">
<h1>Fırsatlar ve Kampanyalar için Abone Olun</h1>
<p>Birçok tedavi için en son indirim kuponlarını, fırsatları ve cashback tekliflerini burada bulabilirsiniz.</p>
</div>
<div class="row">
<div class="col-md-12">
<div class="newsletter">
<form class="newsletter-form">
<div class="row">
<div class="col-md-3">
<div class="field-input">
<input type="text" name="form_name" placeholder="Tam Adınız" required="">
</div>
</div>
<div class="col-md-3">
<div class="field-input">
<input type="email" name="form_email" placeholder="E-posta Adresiniz" required="">
</div>
</div>
<div class="col-md-3">
<div class="field-input">
<input type="text" name="form_phn" placeholder="Telefon Numaranız" required="">
</div>
</div>
<div class="col-md-3">
<button class="#" type="submit">Abone Ol</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
<!--Bülten alanı bitiş-->

<!--Hakkımızda alanı başlangıç-->
<section class="about-us-area choose-area">
<div class="container">
<div class="sec-title text-center">
<h1>Neden Bizi Tercih Etmelisiniz?</h1>
<span class="border"></span>
</div>
<div class="row">
<div class="col-md-12">
<div class="right-content choose-carousel">
<!--Tek kutucuk başlangıç-->
<div class="single-item">
<div class="icon-holder">
<span class="flaticon-social"></span>
</div>
<div class="text">
<h3>Uzman Doktorlar</h3>
<p>Fiziksel olarak zahmetli işleri üstleniyoruz.</p>
</div>
</div>
<!--Tek kutucuk bitiş-->
<div class="single-item">
<div class="icon-holder">
<span class="flaticon-edit"></span>
</div>
<div class="text">
<h3>Ücretsiz Muayene</h3>
<p>Fiziksel olarak zahmetli işleri üstleniyoruz.</p>
</div>
</div>
<div class="single-item">
<div class="icon-holder">
<span class="flaticon-book"></span>
</div>
<div class="text">
<h3>Uygun Fiyatlı Klinik</h3>
<p>Fiziksel olarak zahmetli işleri üstleniyoruz.</p>
</div>
</div>
<div class="single-item">
<div class="icon-holder">
<span class="flaticon-tool"></span>
</div>
<div class="text">
<h3>Son Teknoloji</h3>
<p>Fiziksel olarak zahmetli işleri üstleniyoruz.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!--Hakkımızda alanı bitiş-->


<!-- jQuery ve Ajax için -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

<script>
document.addEventListener('DOMContentLoaded', function () {
// Sayfa yüklendiğinde saatleri gizle
var appointmentTimeSelect = document.getElementById('appointment_time');
appointmentTimeSelect.innerHTML = '<option disabled selected>Saati seçin</option>'; // İlk başta bir seçenek ekle

// Tarih ve kategori değiştirildiğinde saatleri güncelle
function updateAppointmentTimes() {
var category = document.getElementById('category').value; // Kategori
var appointmentDate = document.getElementById('appointment_date').value; // Seçilen tarih
var appointmentTimeSelect = document.getElementById('appointment_time');
appointmentTimeSelect.innerHTML = ''; // Saatleri temizle

// Eğer tarih seçilmemişse saatleri yükleme
if (!appointmentDate || !category) {
appointmentTimeSelect.innerHTML = '<option disabled selected>Önce tarih ve kategori seçin</option>';
return;
}

// Ajax isteğiyle dolu saatleri kontrol et
fetch(/check-appointment-times?date=${appointmentDate}&category=${category})
.then(response => response.json())
.then(data => {
var bookedTimes = data.bookedTimes; // Dolu saatleri al
var allDayBooked = data.allDayBooked; // O günün tamamının dolup dolmadığını al

// Kategorinin dakika aralığı
const timeSlots = {
muayene: 10,
kanal_tedavisi: 60,
dis_cekimi: 10,
dolgu: 30,
dis_tasi_temizligi: 20,
ortodonti: 60,
implant: 90,
dis_beyazlatma: 45,
protez: 60,
roentgen: 10,
pedodonti: 30
};

var interval = timeSlots[category] || 10;
const startHour = 9; // Başlangıç saati
const endHour = 18; // Bitiş saati

// Eğer o gün tamamen dolmuşsa, takvimde o günü seçilemez yap
if (allDayBooked) {
document.getElementById('appointment_date').setAttribute('disabled', 'true');
alert('Bu gün tamamen dolu, lütfen başka bir gün seçin.');
} else {
// Takvimde günün seçilebilir olmasını sağla
document.getElementById('appointment_date').removeAttribute('disabled');
}

// Saatleri eklemek için döngü
for (let hour = startHour; hour <= endHour; hour++) {
for (let min = 0; min < 60; min += interval) {
let totalMinutes = hour * 60 + min;
if (totalMinutes > endHour * 60) break;

let h = Math.floor(totalMinutes / 60);
let m = totalMinutes % 60;

let formattedHour = (h < 10 ? '0' : '') + h;
let formattedMinute = (m < 10 ? '0' : '') + m;

// Eğer bu saat dolu değilse, saat seçeneğini ekle
let option = document.createElement('option');
option.value = formattedHour + ':' + formattedMinute;
option.innerText = formattedHour + ':' + formattedMinute;

// Eğer bu saat doluysa, o saati disabled yap
if (bookedTimes.includes(formattedHour + ':' + formattedMinute)) {
option.disabled = true;
}

// Saat seçeneğini <select> içine ekliyoruz
appointmentTimeSelect.appendChild(option);
}
}
})
.catch(error => {
console.error('Saatler yüklenirken bir hata oluştu:', error);
appointmentTimeSelect.innerHTML = '<option disabled selected>Saati yüklerken hata oluştu</option>';
});
}

// Sayfa yüklendiğinde ve kategori ile tarih değiştirildiğinde saati güncelle
document.getElementById('category').addEventListener('change', updateAppointmentTimes);
document.getElementById('appointment_date').addEventListener('change', updateAppointmentTimes);

// İlk başta tarih ve kategori seçilmediyse saatleri yükleme
updateAppointmentTimes();
});

</script>

<script>
// Bugünün tarihini al
let today = new Date().toISOString().split('T')[0];
document.getElementById('appointment_date').setAttribute('min', today);
</script>



<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>

@if(session('success'))
<script>
Swal.fire({
icon: 'success',
title: 'Randevu başarı ile oluşturuldu!',
text: 'Randevu detay bilgileri e-posta adresinize gönderilmiştir',
confirmButtonText: 'Tamam'
});
</script>
@endif

@if(session('danger'))
<script>
Swal.fire({
icon: 'error',
title: 'Randevu alınamadı!',
text: '{{ session('danger') }}',
confirmButtonText: 'Tamam'
});
</script>
@endif

@endsection

chatgpt pro ya sordum düzeltmelrini sağladım ancak hala istediğim gibi çalışmadı bu arada checkAppointmentTimes route unu da web.php ye ekledim
Kod böyle atılmaz lütfen düzeltin. Kod bloklarına alın.
 
Kod böyle atılmaz lütfen düzeltin. Kod bloklarına alın.

Silebiliyor muyum
Düzelteyim

Kod:
@extends('frontend.main_master')

@section('main')

<style type="text/css">
    #appointment_time {
    display: block;
    width: 100%;
    height: auto;
}
</style>


<!--Breadcrumb alanı başlangıç-->     
<section class="breadcrumb-area" style="background-image: url('{{ asset('frontend/assets/images/resources/breadcrumb-bg.jpg') }}');">
    <div class="container">
        <div class="row">
            <div class="col-md-12">
                <div class="left pull-left">
                    <div class="title">
                        <h1>Randevu</h1>
                    </div>
                </div>
                <div class="right pull-right">
                    <ul>
                        <li><i class="fa fa-home home" aria-hidden="true"></i><a href="{{url('/')}}">Anasayfa</a></li>
                        <li><i class="fa fa-angle-right" aria-hidden="true"></i></li>
                        <li class="active">Randevu</li>
                    </ul>
                </div>   
            </div>
        </div>
    </div>
</section>
<!--Breadcrumb alanı bitiş--> 

<!--Randevu alanı başlangıç-->
<section class="appointment-page">
    <div class="container">
        <div class="sec-title text-center">
            <h1>Randevu Oluştur</h1>
            <span class="border"></span>
            <div class="text-box">
                <p>Aşağıdaki formu kullanarak kolayca randevu oluşturabilirsiniz.</br> Hizmet kategorisini seçtiğinizde, o kategoriye özel uygun saat aralıkları otomatik olarak listelenecektir.</p>
            </div>
        </div>
        <div class="row">
            <div class="appointment-box">
                <div class="col-md-12">
                    <div class="form">
                        <form id="randevuForm" method="POST" action="{{ route('randevu.store') }}">
                            @csrf
                            <div class="row">
                                <div class="col-md-4">
                                    <div class="input-box">
                                        <label>Tam Adınız</label>
                                        <input type="text" name="full_name" placeholder="Tam Adınız" required>
                                    </div>
                                </div>
                                <div class="col-md-4">
                                    <div class="input-box">
                                        <label>Telefon Numaranız</label>
                                        <input type="text" name="phone_number" value="" placeholder="Telefon Numaranız" required="">
                                    </div>
                                </div>
                                <div class="col-md-4">
                                    <div class="input-box">
                                        <label>E-posta Adresiniz</label>
                                        <input type="email" name="email" value="" placeholder="E-posta Adresiniz" required="">
                                    </div>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col-md-4">
                                    <div class="input-box">
                                        <label>Tarih Seçin</label>
                                        <input style="height: 50px;border-radius: 0;border-color: #f5f5f5fa;" class="form-control"  type="date" name="appointment_date" id="appointment_date" required min="{{ \Carbon\Carbon::today()->toDateString() }}">
                                    </div>
                                </div>
                                <div class="col-md-4">
                                    <div class="input-box">
                                        <label id="category_label">Kategori Seçin</label>
                                        <select class="form-control" id="category" name="category" required style="height: 50px;border-radius: 0;border-color: #f5f5f5fa;">
                                            <option value="muayene">Muayene</option>
                                            <option value="kanal_tedavisi">Kanal Tedavisi</option>
                                            <option value="dis_cekimi">Diş Çekimi</option>
                                            <option value="dolgu">Dolgu</option>
                                            <option value="dis_tasi_temizligi">Diş Taşı Temizliği</option>
                                            <option value="ortodonti">Ortodonti</option>
                                            <option value="implant">İmplant</option>
                                            <option value="dis_beyazlatma">Diş Beyazlatma</option>
                                            <option value="protez">Protez Diş</option>
                                            <option value="roentgen">Panoramik Röntgen</option>
                                            <option value="pedodonti">Çocuk Diş Hekimliği</option>
                                        </select>
                                    </div>
                                </div>
                                <div class="col-md-4">                                       
                                        <div class="input-box">
                                            <label>Randevu Saati Seçin</label>
                                            <select style="height: 50px; border-radius: 0; border-color: #f5f5f5fa;" class="form-control" id="appointment_time" name="appointment_time" required>
                                                <!-- Saatler burada dinamik olarak yüklenecek -->
                                            </select>
                                        </div>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col-md-12" style="max-height: 100%;margin-top: 50px;">
                                    <label>Mesajınız</label>
                                    <textarea style="height: 150px" name="message" placeholder="(Dilerseniz bu alanı boş bırakabilirsiniz!)"></textarea>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col-md-12">
                                    <button class="thm-btn bg-1" type="submit">Randevu Oluştur</button>   
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>   
        </div>
    </div>
</section>
<!--Randevu alanı bitiş-->


<!--Bülten alanı başlangıç-->
<section class="newsletter-area" style="background-image:url('{{ asset('frontend/assets/images/resources/newsletter-bg.jpg') }}');">
    <div class="container">
        <div class="sec-title center text-center">
            <h1>Fırsatlar ve Kampanyalar için Abone Olun</h1>
            <p>Birçok tedavi için en son indirim kuponlarını, fırsatları ve cashback tekliflerini burada bulabilirsiniz.</p>
        </div>
        <div class="row">
            <div class="col-md-12">
                <div class="newsletter">
                    <form class="newsletter-form">
                        <div class="row">
                            <div class="col-md-3">   
                                <div class="field-input">
                                    <input type="text" name="form_name" placeholder="Tam Adınız" required="">
                                </div>
                            </div>
                            <div class="col-md-3">   
                                <div class="field-input">
                                    <input type="email" name="form_email" placeholder="E-posta Adresiniz" required="">
                                </div>
                            </div>
                            <div class="col-md-3">   
                                <div class="field-input">
                                    <input type="text" name="form_phn" placeholder="Telefon Numaranız" required="">
                                </div>
                            </div>
                            <div class="col-md-3">
                                <button class="#" type="submit">Abone Ol</button>
                            </div>
                        </div>
                    </form>   
                </div>   
            </div>
        </div>
    </div>
</section>     
<!--Bülten alanı bitiş-->

<!--Hakkımızda alanı başlangıç-->
<section class="about-us-area choose-area">
    <div class="container">
        <div class="sec-title text-center">
            <h1>Neden Bizi Tercih Etmelisiniz?</h1>
            <span class="border"></span>
        </div>
        <div class="row">
            <div class="col-md-12">
                <div class="right-content choose-carousel">
                    <!--Tek kutucuk başlangıç-->
                    <div class="single-item">
                        <div class="icon-holder">
                            <span class="flaticon-social"></span>
                        </div>
                        <div class="text">
                            <h3>Uzman Doktorlar</h3>
                            <p>Fiziksel olarak zahmetli işleri üstleniyoruz.</p>
                        </div>
                    </div>
                    <!--Tek kutucuk bitiş-->
                    <div class="single-item">
                        <div class="icon-holder">
                            <span class="flaticon-edit"></span>
                        </div>
                        <div class="text">
                            <h3>Ücretsiz Muayene</h3>
                            <p>Fiziksel olarak zahmetli işleri üstleniyoruz.</p>
                        </div>
                    </div>
                    <div class="single-item">
                        <div class="icon-holder">
                            <span class="flaticon-book"></span>
                        </div>
                        <div class="text">
                            <h3>Uygun Fiyatlı Klinik</h3>
                            <p>Fiziksel olarak zahmetli işleri üstleniyoruz.</p>
                        </div>
                    </div>
                    <div class="single-item">
                        <div class="icon-holder">
                            <span class="flaticon-tool"></span>
                        </div>
                        <div class="text">
                            <h3>Son Teknoloji</h3>
                            <p>Fiziksel olarak zahmetli işleri üstleniyoruz.</p>
                        </div>
                    </div>
                </div>   
            </div> 
        </div>
    </div>
</section>
<!--Hakkımızda alanı bitiş-->


<!-- jQuery ve Ajax için -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

<script>
document.addEventListener('DOMContentLoaded', function () {
    // Sayfa yüklendiğinde saatleri gizle
    var appointmentTimeSelect = document.getElementById('appointment_time');
    appointmentTimeSelect.innerHTML = '<option disabled selected>Saati seçin</option>'; // İlk başta bir seçenek ekle

    // Tarih ve kategori değiştirildiğinde saatleri güncelle
    function updateAppointmentTimes() {
        var category = document.getElementById('category').value; // Kategori
        var appointmentDate = document.getElementById('appointment_date').value; // Seçilen tarih
        var appointmentTimeSelect = document.getElementById('appointment_time');
        appointmentTimeSelect.innerHTML = ''; // Saatleri temizle

        // Eğer tarih seçilmemişse saatleri yükleme
        if (!appointmentDate || !category) {
            appointmentTimeSelect.innerHTML = '<option disabled selected>Önce tarih ve kategori seçin</option>';
            return;
        }

        // Ajax isteğiyle dolu saatleri kontrol et
        fetch(`/check-appointment-times?date=${appointmentDate}&category=${category}`)
            .then(response => response.json())
            .then(data => {
                var bookedTimes = data.bookedTimes;  // Dolu saatleri al
                var allDayBooked = data.allDayBooked; // O günün tamamının dolup dolmadığını al

                // Kategorinin dakika aralığı
                const timeSlots = {
                    muayene: 10,
                    kanal_tedavisi: 60,
                    dis_cekimi: 10,
                    dolgu: 30,
                    dis_tasi_temizligi: 20,
                    ortodonti: 60,
                    implant: 90,
                    dis_beyazlatma: 45,
                    protez: 60,
                    roentgen: 10,
                    pedodonti: 30
                };

                var interval = timeSlots[category] || 10;
                const startHour = 9; // Başlangıç saati
                const endHour = 18; // Bitiş saati

                // Eğer o gün tamamen dolmuşsa, takvimde o günü seçilemez yap
                if (allDayBooked) {
                    document.getElementById('appointment_date').setAttribute('disabled', 'true');
                    alert('Bu gün tamamen dolu, lütfen başka bir gün seçin.');
                } else {
                    // Takvimde günün seçilebilir olmasını sağla
                    document.getElementById('appointment_date').removeAttribute('disabled');
                }

                // Saatleri eklemek için döngü
                for (let hour = startHour; hour <= endHour; hour++) {
                    for (let min = 0; min < 60; min += interval) {
                        let totalMinutes = hour * 60 + min;
                        if (totalMinutes > endHour * 60) break;

                        let h = Math.floor(totalMinutes / 60);
                        let m = totalMinutes % 60;

                        let formattedHour = (h < 10 ? '0' : '') + h;
                        let formattedMinute = (m < 10 ? '0' : '') + m;

                        // Eğer bu saat dolu değilse, saat seçeneğini ekle
                        let option = document.createElement('option');
                        option.value = formattedHour + ':' + formattedMinute;
                        option.innerText = formattedHour + ':' + formattedMinute;

                        // Eğer bu saat doluysa, o saati disabled yap
                        if (bookedTimes.includes(formattedHour + ':' + formattedMinute)) {
                            option.disabled = true;
                        }

                        // Saat seçeneğini <select> içine ekliyoruz
                        appointmentTimeSelect.appendChild(option);
                    }
                }
            })
            .catch(error => {
                console.error('Saatler yüklenirken bir hata oluştu:', error);
                appointmentTimeSelect.innerHTML = '<option disabled selected>Saati yüklerken hata oluştu</option>';
            });
    }

    // Sayfa yüklendiğinde ve kategori ile tarih değiştirildiğinde saati güncelle
    document.getElementById('category').addEventListener('change', updateAppointmentTimes);
    document.getElementById('appointment_date').addEventListener('change', updateAppointmentTimes);

    // İlk başta tarih ve kategori seçilmediyse saatleri yükleme
    updateAppointmentTimes();
});

</script>

<script>
    // Bugünün tarihini al
    let today = new Date().toISOString().split('T')[0];
    document.getElementById('appointment_date').setAttribute('min', today);
</script>



<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>

@if(session('success'))
<script>
    Swal.fire({
        icon: 'success',
        title: 'Randevu başarı ile oluşturuldu!',
        text: 'Randevu detay bilgileri e-posta adresinize gönderilmiştir',
        confirmButtonText: 'Tamam'
    });
</script>
@endif

@if(session('danger'))
<script>
    Swal.fire({
        icon: 'error',
        title: 'Randevu alınamadı!',
        text: '{{ session('danger') }}',
        confirmButtonText: 'Tamam'
    });
</script>
@endif

@endsection

Bu blade dosyası

Kod:
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Randevu;
use Illuminate\Support\Carbon;
use App\Mail\RandevuOzelMaili;
use App\Mail\RandevuDurumGuncellemeMaili;
use App\Mail\RandevuTamamlandiMaili;
use Illuminate\Support\Facades\Mail; // Mail sınıfını dahil ettik

class RandevuController extends Controller
{
    public function index(Request $request)
    {
        // Veritabanındaki tüm randevuları al
        $randevular = Randevu::orderBy('created_at', 'desc')->get();

        // Kategoriler için harita
        $categoryMap = [
            'muayene' => 'Muayene',
            'kanal_tedavisi' => 'Kanal Tedavisi',
            'dis_cekimi' => 'Diş Çekimi',
            'dolgu' => 'Dolgu',
            'dis_tasi_temizligi' => 'Diş Taşı Temizliği',
            'ortodonti' => 'Ortodonti',
            'implant' => 'İmplant',
            'dis_beyazlatma' => 'Diş Beyazlatma',
            'protez' => 'Protez',
            'roentgen' => 'Röntgen',
            'pedodonti' => 'Pedodonti'
        ];

        // Eğer AJAX isteği yapılıyorsa, JSON formatında döndürüyoruz
        if ($request->ajax()) {
            return response()->json([
                'randevular' => $randevular // Sayfalama ile gelen randevular
            ]);
        }

        // Veriyi view'a gönder
        return view('admin.randevular.randevu_liste', compact('randevular', 'categoryMap'));  // compact() ile veri gönderiliyor
    }

    // Yeni randevu eklemek için
    public function store(Request $request)
    {
        // Form verilerini doğrulama
        $validated = $request->validate([
            'full_name' => 'required|string|max:255',
            'phone_number' => 'required|string|max:20',
            'email' => 'required|email', // E-posta alanını ekliyoruz
            'appointment_date' => 'required|date|after_or_equal:today',
            'appointment_time' => 'required|date_format:H:i',
            'category' => 'required|string', // Kategori kontrolü
            'message' => 'nullable|string',
        ]);

        // Aynı tarih ve saatte başka bir randevu olup olmadığını kontrol et
        $existingAppointment = Randevu::where('appointment_date', $validated['appointment_date'])
                                       ->where('appointment_time', $validated['appointment_time'])
                                       ->first();

        if ($existingAppointment) {
            return redirect()->back()->with('danger',  'Geçerli saatte zaten bir randevu alınmış. Lütfen başka bir saat seçin.');
        }

        // Randevu oluşturma
        $appointment = Randevu::create([
            'full_name' => $validated['full_name'],
            'phone_number' => $validated['phone_number'],
            'email' => $validated['email'],
            'appointment_date' => $validated['appointment_date'],
            'appointment_time' => $validated['appointment_time'],
            'category' => $validated['category'], // Kategori ekliyoruz
            'status' => 'pending', // Varsayılan durum
            'message' => $validated['message'],
        ]);

        // Randevu bilgilerini e-posta için hazırlıyoruz
        $appointmentDetails = [
            'full_name' => $appointment->full_name,
            'appointment_date' => $appointment->appointment_date,
            'appointment_time' => $appointment->appointment_time,
            'category' => $appointment->category
        ];

        // Kullanıcıya randevu onayı e-postası gönderme
        Mail::to($validated['email'])->send(new RandevuOzelMaili($appointmentDetails));

        session()->put('new_appointment', 'Yeni bir randevunuz var!');

        return redirect()->back()->with('success',  'Randevu Başarı ile oluşturuldu!');
    }

    // Randevuyu iptal etme
    public function cancel($id)
    {
        // İlgili randevuyu bul
        $appointment = Randevu::findOrFail($id);

        // Randevu durumunu 'canceled' olarak güncelle
        $appointment->update(['status' => 'canceled']);

        // İptal mesajı döndür
        return response()->json(['message' => 'Randevu iptal edildi']);
    }

        public function updateStatus(Request $request, $id)
        {
            $randevu = Randevu::findOrFail($id);

            // Durum güncellemeyi kontrol et
            $randevu->status = $request->input('status');
            $randevu->save();

            // Kategori ve durum çevirileri
            $categoryMap = [
                'muayene' => 'Muayene',
                'kanal_tedavisi' => 'Kanal Tedavisi',
                'dis_cekimi' => 'Diş Çekimi',
                'dolgu' => 'Dolgu',
                'dis_tasi_temizligi' => 'Diş Taşı Temizliği',
                'ortodonti' => 'Ortodonti',
                'implant' => 'İmplant',
                'dis_beyazlatma' => 'Diş Beyazlatma',
                'protez' => 'Protez',
                'roentgen' => 'Röntgen',
                'pedodonti' => 'Pedodonti'
            ];

            $statusMap = [
                'pending' => 'Beklemede',
                'confirmed' => 'Onaylı',
                'completed' => 'Tamamlandı',
                'canceled' => 'İptal Edildi'
            ];

            // Randevu bilgilerini e-posta için hazırlıyoruz (map'lenmiş haliyle)
            $appointmentDetails = [
                'full_name' => $randevu->full_name,
                'appointment_date' => $randevu->appointment_date,
                'appointment_time' => $randevu->appointment_time,
                'category' => $categoryMap[$randevu->category] ?? $randevu->category,
                'status' => $statusMap[$randevu->status] ?? $randevu->status,
            ];

            // Kullanıcıya randevu durumu güncelleme e-postası gönderme
            if ($randevu->status === 'completed') {
                Mail::to($randevu->email)->send(new RandevuTamamlandiMaili($appointmentDetails));
            } else {
                Mail::to($randevu->email)->send(new RandevuDurumGuncellemeMaili($appointmentDetails));
            }

            return redirect()->back()->with('success',  'Randevu başarıyla güncellendi ve e-posta gönderildi.');
        }



    public function delete($id, Request $request)
    {
        // Randevuyu ID'ye göre bul
        $randevu = Randevu::findOrFail($id);

        // Randevuyu sil
        $randevu->delete();

        // AJAX ile gelen silme isteği ise JSON formatında yanıt gönderiyoruz
        if ($request->ajax()) {
            return response()->json([
                'message' => 'Randevu başarıyla silindi.'
            ]);
        }

        return redirect()->back()->with('success', 'Randevu başarıyla silindi.');
    }

        public function checkAppointmentTimes(Request $request)
        {
            $date = $request->input('date'); // Seçilen tarih
            $category = $request->input('category'); // Seçilen kategori

            // Aynı tarih ve saatte tüm kategorilerde alınmış randevuları getir
            $appointments = Randevu::where('appointment_date', $date)->get();

            // Eğer o gün doluysa, o günü seçilemez yapalım
            $bookedTimes = [];
            $allDayBooked = false;
            
            // Eğer o günün tamamı dolmuşsa, allDayBooked'ı true yapıyoruz
            if ($appointments->count() >= 9 * 60) { // 9:00 - 18:00 arasında 9 saat x 60 dakika = 540 dakika
                $allDayBooked = true;
            }

            // Dolu saatleri saklamak için bir dizi oluşturuyoruz
            foreach ($appointments as $appointment) {
                $bookedTimes[] = $appointment->appointment_time;
            }

            // Dolu saatler ve o günün tamamının dolu olduğu bilgisini JSON formatında döndürüyoruz
            return response()->json([
                'bookedTimes' => $bookedTimes,
                'allDayBooked' => $allDayBooked
            ]);
        }






}

Buda controller

Burada randevu sistemi işliyor kodlar çalışıyor sadece randevu saatini doluysa seçilemez ve o gün tüm randevular alındı ise tarih kısmında o günü kapatacak
 
Son düzenleme:
Kodu inceledim backend kısmında ekstra olarak tüm dolu günleri seçebileceğin bir route yazabilirsin ve bunu scriptte seslersin. Bu şekilde tüm dolu günleri kullanıcıya göstermezsin. Diğer dediğini zaten yapıyorsun burda ?

if (bookedTimes.includes(formattedHour + ':' + formattedMinute)) {
option.disabled = true;
}
 
Hocam anlamadım ki bende link paylaşsam inceleyebilir misiniz mesela randevu alınmış bir randevu tarihi söylesem inceleme sağlayabilir misiniz? birde yonetim panelinde randevu durumu güncelleme var bunuda şimdi canlı da izlediğimde her zaman son randevunun durumunu güncelleme yaptırıyor diğerleride çalışmıyor

Yani anlamadığım her şey doğru ise neden canlıda göremiyoruz bunu anlamadım

Bir de tam anlatmak istediğimi anlatabildim mi bilmiyorum ama örneğin bir tarihe birisi saat 09 00'a randevu aldı diyelim bir başkası girdiğinde o tarihte yine saat 09 00'u gösteriyor fakat seçtiğinde bu saat dolu hatası veriyor. Benim istediğim eğer o saat doluysa o saati diğer randevu alan kişi seçilemez olarak yani dolu olarak görmesi lazım. Şu an aynı gün aynı saati seçince randevu saati dolu hatası verdiriyorum. Eğer saat seçilemez görünürse bu şekilde daha hızlı seçilebilir randevu oluşturmak istiyorum

Hocam hallettim kodu ben tekrar inceledim saat kaydını H: S olarak saklıyormuşum backend de ama scriptte h:s:i olarak tutmaya çalıştığım için görmüyordu diye düşünüyorum backendde de H:s:i olarak güncelleme sağladım şu an sorunsuz çalışıyor.
 
Son düzenleme:

Technopat Haberler

Yeni konular

Geri
Yukarı