<?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:

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