test

from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from .models import Meeting, BlockedDates, GenkRandevu, BrasschaatRandevu, WorkingHours, Settings

class AppointmentAdmin(admin.ModelAdmin):
    list_display = ('name', 'email', 'location', 'get_date_date', 'explanation')
    list_filter = ['location', 'history', 'moment']
    search_fields = ['name', 'email']

    def get_tarih_saat(self, obj):
        return f"{obj.history} {obj.moment}"
    get_tarih_saat.short_description = 'Date and Time'

admin.site.register(Meeting, AppointmentAdmin)

class SettingsAdmin(admin.ModelAdmin):
    list_display = ('interval',)

admin.site.register(Settings, SettingsAdmin)

class UserAdmin(BaseUserAdmin):
    list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')

class GenkRandevuAdmin(admin.ModelAdmin):
    list_display = ('name', 'email', 'get_date_date', 'explanation')
    list_filter = ['history', 'moment']
    search_fields = ['name', 'email']

    def get_tarih_saat(self, obj):
        return f"{obj.history} {obj.moment}"
    get_tarih_saat.short_description = 'Date and Time'

    def get_queryset(self, request):
        return super().get_queryset(request).filter(location='genk')

class BrasschaatRandevuAdmin(admin.ModelAdmin):
    list_display = ('name', 'email', 'get_date_date', 'explanation')
    list_filter = ['history', 'moment']
    search_fields = ['name', 'email']

    def get_tarih_saat(self, obj):
        return f"{obj.history} {obj.moment}"
    get_tarih_saat.short_description = 'Date and Time'

    def get_queryset(self, request):
        return super().get_queryset(request).filter(location='brass chat')

@admin.register(WorkingHours)
class WorkingHoursAdmin(admin.ModelAdmin):
    list_display = ('location', 'day', 'start_time', 'end_time')
    ordering = ['location', 'day']

admin.site.unregister(User)
admin.site.register(User, UserAdmin)
admin.site.register(GenkRandevu, GenkRandevuAdmin)
admin.site.register(BrasschaatRandevu, BrasschaatRandevuAdmin)

@admin.register(BlockedDates)
class BlockedDatesAdmin(admin.ModelAdmin):
    list_display = ('date',), admin.py file,
from django.conf import settings
from django import forms
from .models import Meeting
from django.utils.translation import gettext_lazy as _

class LanguageForm(forms.form):
    language = forms.ChoiceField(choices=[(code, name) for code, name in settings.LANGUAGES], label=_("Language"))

class AppointmentForm(forms.ModelForm):
    name = forms.CharField(
        label=_('Name'),
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('Name')})
    )
    e-mail = forms.EmailField(
        label=_('E-mail'),
        widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': _('E-mail')})
    )
    phone = forms.CharField(
        label=_('Telephone'),
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('Telephone')})
    )
    history = forms.DateField(
        label=_('History'),
        widget=forms.DateInput(attrs={'class': form-control datepicker, 'type': 'date', 'placeholder': _('History')})
    )
    moment = forms.TimeField(
        label=_('Moment'),
        widget=forms.TimeInput(attrs={'class': form-control timepicker, 'type': 'text', 'placeholder': _('Moment')})
    )
    explanation = forms.CharField(
        label=_('Explanation'),
        widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': _(How many people are you making a reservation for?)})
    )

    class Meta:
        model = Meeting
        fields = ['name', 'email', 'telephone', 'history', 'moment', 'explanation']

,forms.py file, 
from django.db import models
from django.utils.translation import gettext as _

LOCATION_CHOICES = [
    ('genk', 'Genk's Pompadour'),
    ('brass chat', Pomandi Brasschaat),
]

class Meeting(models.Model):
    location = models.CharField(max_length=50, choices=LOCATION_CHOICES, null=False, blank=False)
    name = models.CharField(max_length=50, null=False, blank=False)
    e-mail = models.EmailField(max_length=255, null=False, blank=False)
    phone = models.CharField(max_length=20, null=False, blank=False)
    history = models.DateField(null=True)
    moment = models.TimeField(null=True)
    explanation = models.TextField(max_length=500, null=True, blank=True)

    def save(self, *args, **kwargs):
        if not self.location:
            if self._meta.model_name == "genkrandevu":
                self.location = 'genk'
            Elif self._meta.model_name == "brasschaatrandevu":
                self.location = 'brass chat'
        super(Meeting, self).save(*args, **kwargs)

    def __str__(self):
        return self.name

class WorkingHours(models.Model):
    max_appointments = models.PositiveIntegerField(default=1, help_text="Maximum number of appointments for this time zone")

    DAY_CHOICES = [
        (0, 'Monday'),
        (1, 'Tuesday'),
        (2, 'Wednesday'),
        (3, 'Thursday'),
        (4, 'Only'),
        (5, 'Saturday'),
        (6, 'Sunday'),
    ]

    location = models.CharField(max_length=50, choices=LOCATION_CHOICES, null=True, blank=True)
    day = models.Positive Small Integer Field(choices=DAY_CHOICES)
    start_time = models.TimeField()
    end_time = models.TimeField()

    class Meta:
        unique_together = ['location', 'day']

    def __str__(self):
        return f"{self.get_location_display()} - {self.get_day_display()} - {self.start_time} - {self.end_time}"

class GenkRandevu(Meeting):
    class Meta:
        proxy = True
        verbose_name = 'Genk Appointment'
        verbose_name_plural = 'Genk Appointments'

class BrasschaatRandevu(Meeting):
    class Meta:
        proxy = True
        verbose_name = Brasschaat Rendezvous
        verbose_name_plural = Brasschaat Encounters

class BlockedDates(models.Model):
    location = models.CharField(max_length=50, choices=LOCATION_CHOICES, null=False, blank=False)
    date = models.DateField()

    class Meta:
        unique_together = ['location', 'date']

    def __str__(self):
        return f"{self.get_location_display()} - {self.date.strftime('%Y-%m-%d')}"


class Settings(models.Model):
    location = models.CharField(max_length=50, choices=LOCATION_CHOICES, null=True, blank=True)
    interval = models.PositiveIntegerField(default=20)
,models.py file, 
from django.http import JsonResponse
from django.shortcuts import render, redirect
from .models import Meeting, BlockedDates, WorkingHours, Settings
from .forms import AppointmentForm, LanguageForm
from django.utils.translation import gettext as _
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.conf import settings
from django.utils import translation

def set_language(request):
    if request.method == "POST":
        form = LanguageForm(request.POST)
        if form.is_valid():
            user_language = form.cleaned_data['language']
            translation.activate(user_language)
            request.session["django_language"] = user_language
            return redirect('location_choice')
        else:
            print("Form is not valid!")
            print(form.errors)
    else:
        form = LanguageForm()
    return render(request, appointment_application/set_language.html, {'form': form})

def location_choice(request):
    if request.method == "POST":
        chosen_location = request.POST.get('location')
        request.session['chosen_location'] = chosen_location
        return redirect('create_appointment')
    return render(request, appointment_application/location_choice.html)

def randevu_listesi(request):
    appointments = Meeting.objects.all().order_by('history', 'moment')
    return render(request, appointment_application/appointment_list.html, {'appointments': appointments})

def randevu_olustur(request, location=None):
    if not location:
        location = request.session.get('chosen_location', 'default_location')
        return redirect('create_appointment', location=location)

    if request.method == "POST":
        form = AppointmentForm(request.POST)
        if form.is_valid():
            history = form.cleaned_data['history']
            moment = form.cleaned_data['moment']

            # Blocked Dates Control
            if BlockedDates.objects.filter(date=history).exists():
                form.add_error('history', "An appointment cannot be made for this date.")
                return render(request, appointment_application/appointment_create.html, {'form': form, 'location': location})

            # Working Hours and Days Control
            day_of_week = history.weekday()
            try:
                working_hours = WorkingHours.objects.get(day=day_of_week, location=location)
                if moment < working_hours.start_time or moment > working_hours.end_time:
                    form.add_error('moment', The selected hour is outside of working hours.)
                    return render(request, appointment_application/appointment_create.html, {'form': form})
            except WorkingHours.DoesNotExist:
                form.add_error('history', The working hours for the selected day are not defined.)
                return render(request, appointment_application/appointment_create.html, {'form': form})

            meeting = form.save(commit=False)
            meeting.location = location
            meeting.save()
            return redirect('appointment_detail', randevu_id=meeting.id)
    else:
        form = AppointmentForm()
    return render(request, appointment_application/appointment_create.html, {'form': form})
def get_working_hours(request, location, day_of_week):
    # we are getting the location information from the URL, so there is no need for the line below.
    # location = request.session.get('chosen_location', 'default_location')
    try:
        working_hours = WorkingHours.objects.get(day=day_of_week, location=location)
        return JsonResponse({
            'start': working_hours.start_time.strftime('%H:%M'),
            'end': working_hours.end_time.strftime('%H:%M')
        })
    except WorkingHours.DoesNotExist:
        return JsonResponse({'error': Working hours not set for this day}, status=404)

def get_working_days(request, location):
    # we are getting the location information from the URL, so there is no need for the line below.
    # location = request.session.get('chosen_location', 'default_location')
    working_days = WorkingHours.objects.filter(location=location).values_list('day', flat=True)
    return JsonResponse(list(working_days), safe=False)


def randevu_detay(request, randevu_id):
    meeting = Meeting.objects.get(id=randevu_id)
    return render(request, appointment_application/appointment_detail.html, {'meeting': meeting})

def blocked_dates(request):
    # Get the location information selected by the user
    location = request.session.get('chosen_location', 'default_location')

    # Filter blocked dates by location
    dates = BlockedDates.objects.filter(location=location).values_list('date', flat=True)

    print(dates)  # Move this line here

    # Convert dates to string format
    date_strings = [date.isoformat() for date in dates]

    # Return the results in JSON format
    return JsonResponse(date_strings, safe=False)




def get_appointments_for_date(request):
    selected_date = request.GET.get('date')
    appointments = Meeting.objects.filter(history=selected_date).values_list('moment', flat=True)
    return JsonResponse(list(appointments), safe=False)

def get_appointment_interval(request, location):
    settings = Settings.objects.filter(location=location).first()
    interval = settings.interval if settings else 20  # If settings are not configured, default to 20 minutes
    return JsonResponse({"interval": interval})

,views.py file, 
# appointment_application/urls.py

from django.urls import path
from . import views
from django.conf.urls.i18n import i18n_patterns

urlpatterns = [
   
    path('', views.randevu_listesi, name='appointment_list'),
   path(appointment//'', views.randevu_olustur, name='create_appointment'),
    path(appointment_detail//, views.randevu_detay, name='appointment_detail'),
    path('blocked_dates/', views.blocked_dates, name='blocked_dates'),
    path('set-language/', views.set_language, name='set_language'),
    path('location_choice/', views.location_choice, name='location_choice'),
    path(nl/get_working_hours///, views.get_working_hours, name='get_working_hours'),
    path(nl/get_working_days//, views.get_working_days, name='get_working_days'),
    path(get_appointments_for_date/, views.get_appointments_for_date, name=get_appointments_for_date),
    path(get_appointment_interval/, views.get_appointment_interval, name=get_appointment_interval),



]

,urls.py file,

DOCTYPE html>
{% load static %}
{% load i18n %}

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">

<link rel="stylesheet" href="{% static appointment_application/css/styles.css %}">

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">

<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js">script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js">script>

<script src="https://cdn.jsdelivr.net/npm/flatpickr">script>

<div class="container py-5">
    <h1 class="mb-5 text-center display-4">{% trans "New Appointment" %}h1>

    <div class="row justify-content-center">
        <div class="col-12 col-md-8">
           
            <form method="post">


                {% csrf_token %}
                {% for field in form %}
                <div class="form-group">
                    <label for="displayedTime" class="col-lg-2 control-label display-4">{{ field.label }}label>
                    <div class="col-lg-10">
                        {% if field.name != "moment" %}
                        {{ field }}
                        {% else %}
                       
                        <input type="text" id="displayedTime" class="form-control" readonly>
                       
                        <div id="timeButtonsContainer">div>
                       
                        <input type="hidden" id="id_saat" name="moment" autocomplete="off">
                        {% endif %}
                       
                        {% if field.errors %}
                        <div class="alert alert-danger">
                            {{ field.errors|join:", " }}
                        div>
                        {% endif %}
                       
                       
                    div>
                div>
                {% endfor %}
                <div class="form-group">
                    <div class="col-lg-offset-2 col-lg-10">
                        <button class="btn btn-primary btn-lg btn-block">{% trans "Create an appointment" %}button>
                    div>
                div>
            form>
        div>
    div>
div>

<style>
    .flatpickr-day.disabled, .flatpickr-day.disabled:hover {
        background: red !important;
        cursor: not-allowed;
    }
style>

<script>
    $(document).ready(function() {
        $("#timeButtonsContainer").hide();  // Sayfa yüklendiğinde saat seçim butonlarını gizle

        // Engellenen tarihleri al
        $.getJSON('{% url "blocked_dates" %}', function(blockedDates) {
            // Çalışma günlerini al
            $.getJSON('{% url "get_working_days" %}', function(workingDays) {
                // Engellenen tarihlerle çalışma günlerini birleştir
                was disabledDates = getDisabledDates(blockedDates, workingDays);
               
                // Flatpickr ayarları
                $("#id_date").flatpickr({
                    dateFormat: "Y-m-d",
                    disable: disabledDates,
                    minDate: "today",
                    onChange: function(selectedDates, dateStr, instance) {
                        if (selectedDates.length > 0) {
                            was dayOfWeek = selectedDates[0].getDay();
                            $.getJSON('{% url "get_working_hours" day_of_week=0 %}'.replace('0', dayOfWeek), function(workHours) {
                                was availableTimes = generateTimeSlots(workHours.start, workHours.end);
   
                                // Seçilen tarihte alınmış randevuları kontrol et
                                $.getJSON(/get_appointments_for_date/, {date: dateStr}, function(takenTimes) {
                                    availableTimes = availableTimes.filter(function(time) {
                                        return !takenTimes.includes(time);
                                    });
   
                                    populateTimeButtons(availableTimes);
                                });
                            });
                        }
                    }
                });
            });
        });
    });
   
    // Engellenen tarihlerle çalışma günlerini birleştir
    function getDisabledDates(blockedDates, workingDays) {
        was disabledDates = blockedDates.slice(); // Engellenen tarihleri kopyala
        was currentDate = new Date();
        for (was i = 0; i < 365; i++) { // Bir yıl içindeki tüm tarihleri kontrol et
            was dayOfWeek = currentDate.getDay();
            if (!workingDays.includes(dayOfWeek)) {
                disabledDates.push(formatDate(currentDate));
            }
            currentDate.setDate(currentDate.getDate() + 1);
        }
        return disabledDates;
    }
   
    // Tarihi "YYYY-MM-DD" formatına dönüştür
    function formatDate(date) {
        was day = date.getDate();
        was month = date.getMonth() + 1;
        was year = date.getFullYear();
        return year + '-' + (month < 10 ? '0' : '') + month + '-' + (day < 10 ? '0' : '') + day;
    }
   
    function populateTimeButtons(availableTimes) {
        was container = $("#timeButtonsContainer");
        container.empty();  // Önceki butonları temizle
   
        availableTimes.forEach(function(time) {
            was button = $(")
                .addClass("btn btn-primary time-button")
                .text(time)
                .click(function() {
                    $("#current_id").val(time);  // Gizli saat input alanını doldur
                    $("#displayedTime").val(time);  // Seçilen saati göster
                    container.hide();  // Saat seçim butonlarını gizle
                });
            container.append(button);
        });
   
        container.show();  // Saat butonlarını göster
   
        // Saat seçim butonları gösterildiğinde, dış tıklama ile gizleme işlevini ekleyin
        $(document).click(function(event) {
            if (!$(event.target).closest("#id_date, .time-button").length) {
                container.hide();
            }
        });
    }
   
   


    function generateTimeSlots(start, end) {
        was timeSlots = [];
        was currentTime = new Date(`1970-01-01 ${start}:00`);
        was endTime = new Date(`1970-01-01 ${end}:00`);
       
        // Interval değerini API'den alın
        $.ajax({
            url: /get_appointment_interval/,
            async: false,
            dataType: 'json',
            success: function(data) {
                was interval = data.interval * 60000;  // dakikayı milisaniyeye çevir
   
                while (currentTime < endTime) {
                    was hours = String(currentTime.getHours()).roadStart(2, '0');
                    was minutes = String(currentTime.getMinutes()).roadStart(2, '0');
                    timeSlots.push(`${hours}:${minutes}`);
                    currentTime = new Date(currentTime.getTime() + interval);
                }
            }
        });
   
        return timeSlots;
    }

    // Lokasyon değerini dinamik olarak formun action attribute'una ekleyen fonksiyon
function updateFormActionWithLocation() {
    was locationValue = "{{ request.session.chosen_location }}";  // Django template dilini kullanarak session'dan lokasyon değerini alıyoruz
    was formActionURL = "{% url 'randevu_olustur' lokasyon='PLACEHOLDER' %}".replace('PLACEHOLDER', locationValue);
    $("form").attr("action", formActionURL);
}

// Formun submit edilmesi öncesinde lokasyon değerini formun action attribute'una ekleyin
$("form").submit(function() {
    updateFormActionWithLocation();
});

   
script>
,appointmentprotection.html file