diff --git a/README.md b/README.md index c5cff9d..341df79 100644 --- a/README.md +++ b/README.md @@ -60,12 +60,14 @@ Le visiteur doit pouvoir : * témoignage ## TO DO - -* remplir les détails des logements et ajouter les photos dynamiquement -* afficher le logo -* Gestion du calendrier -* Ajout du formulaire de réservation sur la page détail -* Ajouter la page de paiement -* Les photos de la page à propos +* Ajouter un bouton réserver maintenant avant le résumé => formulaire en bas * formatter la page réservation +* Formatter la page de remerciement (expliquer la suite) * designer la page d'accueil +* remplir les détails des logements et ajouter les photos dynamiquement +* Les photos de la page à propos +* écrire les mentions légales +* Gestion du calendrier +* Ajout page/module de paiement +* changer la couleur des liens hypertextes +* changer l'adresse de l'admin diff --git a/rental/forms.py b/rental/forms.py new file mode 100644 index 0000000..6007296 --- /dev/null +++ b/rental/forms.py @@ -0,0 +1,35 @@ +from django import forms +from .models import Reservation, Place, Guest +from phonenumber_field.modelfields import PhoneNumberField + + +class ReservationForm(forms.Form): + PLACES=(('T2','T2'), ('T3','T3'),) + name = forms.CharField( + label="", + max_length=100, + min_length=4, + widget=forms.TextInput(attrs={'class': 'form-control form-control-lg form-control-a', 'placeholder': 'Nom *'}), + required=True) + email = forms.EmailField( + label = '', + widget=forms.EmailInput(attrs={'class': 'form-control form-control-lg form-control-a', 'placeholder': 'Email *'}), + required=True + ) + phone = forms.CharField( + label='', + max_length=100, + min_length=4, + widget=forms.TextInput(attrs={'class': 'form-control form-control-lg form-control-a', 'placeholder': 'Téléphone *'}), + required=True) + place = forms.ChoiceField( + label = '', + widget=forms.Select(attrs={'class': 'form-control form-control-lg form-control-a'}), + required=True, + choices=PLACES) + message = forms.CharField( + label='', + max_length=100, + min_length=4, + widget=forms.Textarea(attrs={'class': 'form-control', 'cols': '45', 'rows':'8', 'placeholder': 'Message *'}), + required=True) diff --git a/rental/models.py b/rental/models.py index a3dea0e..becbc82 100644 --- a/rental/models.py +++ b/rental/models.py @@ -12,9 +12,13 @@ class Place(models.Model): name=models.CharField(max_length=10, unique=True) pictures=models.ImageField(upload_to="uploads/",null=True,blank=True) description=models.TextField(blank=True) + info=models.TextField(blank=True) subname=models.CharField(max_length=100, blank=True) tagline=models.CharField(max_length=100, blank=True) price=models.DecimalField(max_digits=6, decimal_places=2, null=True) + surface=models.IntegerField(null=True,blank=True) + beds=models.IntegerField(null=True,blank=True) + max_occupation=models.IntegerField(null=True,blank=True) class Guest(models.Model): @@ -38,6 +42,7 @@ class Reservation(models.Model): place=models.OneToOneField(Place,on_delete=models.CASCADE) guest=models.ForeignKey(Guest,on_delete=models.CASCADE) + message=models.TextField(blank=True) class Testimonial(models.Model): diff --git a/rental/static/rental/css/style.css b/rental/static/rental/css/style.css index c697bc3..1933a0b 100644 --- a/rental/static/rental/css/style.css +++ b/rental/static/rental/css/style.css @@ -3,6 +3,10 @@ body { color: #555555; } +html { + scroll-behavior: smooth; +} + h1, h2, h3, @@ -121,6 +125,10 @@ a:hover { /*------/ Bg Image /------*/ +.logo { + height: 60px; +} + .bg-image { background-repeat: no-repeat; background-attachment: fixed; diff --git a/rental/templates/rental/base.html b/rental/templates/rental/base.html index 6d651af..b21e5f0 100644 --- a/rental/templates/rental/base.html +++ b/rental/templates/rental/base.html @@ -126,7 +126,7 @@ - + VillaFleurie - + {% csrf_token %} + {{ form.as_p }} +

diff --git a/rental/templates/rental/merci.html b/rental/templates/rental/merci.html new file mode 100644 index 0000000..195ebf8 --- /dev/null +++ b/rental/templates/rental/merci.html @@ -0,0 +1,4 @@ +{% extends 'rental/base.html' %} +{% load static %} + +

merci

diff --git a/rental/templates/rental/reservation.html b/rental/templates/rental/reservation.html index 7ec3d28..795e681 100644 --- a/rental/templates/rental/reservation.html +++ b/rental/templates/rental/reservation.html @@ -31,6 +31,91 @@ + + + +
diff --git a/rental/urls.py b/rental/urls.py index 61578e8..2115bb2 100644 --- a/rental/urls.py +++ b/rental/urls.py @@ -7,6 +7,6 @@ app_name = 'rental' urlpatterns = [ path('', views.Accueil.as_view(), name='index'), path('hebergements/', views.ListeLocation.as_view(), name='list_place'), - path('/', views.Location.as_view(), name='detail_place'), - # path('/', views.location, name='detail_place'), + # path('/', views.Location.as_view(), name='detail_place'), + path('/', views.location, name='detail_place'), ] diff --git a/rental/views.py b/rental/views.py index e2a110a..fc726e0 100644 --- a/rental/views.py +++ b/rental/views.py @@ -3,14 +3,8 @@ from django.views.generic import ListView, DetailView, CreateView, UpdateView, D from .models import Testimonial, Reservation, Guest, Place from django.urls import reverse_lazy from django.views.generic.base import TemplateView - - -# Réservation : dans le detail_place.html ajouter un formulaire (if method = post …) -# Paiement : payer -# Remerciement après loocation -# Contact -# À propos -# Légal & CGU +from.forms import ReservationForm +from django.db import IntegrityError class Accueil(ListView): @@ -18,34 +12,107 @@ class Accueil(ListView): template_name = 'rental/index.html' context_object_name = 'places' + class ListeLocation(ListView): model = Place template_name = 'rental/list_place.html' context_object_name = 'places' -class Location(DetailView): - model = Place - template_name = 'rental/detail_place.html' - context_object_name = 'place' - def get_object(self, queryset=None): - place_name = self.kwargs.get('place_name', None) - return get_object_or_404(Place, name=place_name) +def location(request, place_name): + place = get_object_or_404(Place, name=place_name) + context = {'place' : place} + if request.method == 'POST': + form = ReservationForm(request.POST)#, error_class=ParagraphErrorList) + if form.is_valid(): + name = form.cleaned_data['name'] + email = form.cleaned_data['email'] + phone = form.cleaned_data['phone'] + message = form.cleaned_data['message'] + place_name = form.cleaned_data['place'] + try: + guest = Guest.objects.filter(email=email) + if not guest.exists(): + guest = Guest.objects.create( + email=email, + name=name + ) + else: + guest = guest.first() + + place = get_object_or_404(Place, name=place_name) + reservation = Reservation.objects.create( + guest=guest, + place=place, + message=message + ) + context = { + 'guest': guest, + 'place': place + } + return render(request, 'rental/merci.html', context) + except IntegrityError: + form.errors['internal'] = "Une erreur interne est apparue. \ + Merci de recommencer votre requête." + else: + form = ReservationForm() + context['form'] = form + context['errors'] = form.errors.items() + return render(request, 'rental/detail_place.html', context) + + +def reservation(request): + if request.method == 'POST': + form = ReservationForm(request.POST)#, error_class=ParagraphErrorList) + if form.is_valid(): + name = form.cleaned_data['name'] + email = form.cleaned_data['email'] + phone = form.cleaned_data['phone'] + message = form.cleaned_data['message'] + place_name = form.cleaned_data['place'] + try: + guest = Guest.objects.filter(email=email) + if not guest.exists(): + guest = Guest.objects.create( + email=email, + name=name + ) + else: + guest = guest.first() + place = get_object_or_404(Place, name=place_name) + reservation = Reservation.objects.create( + guest=guest, + place=place, + message=message + ) + context = { + 'guest': guest, + 'place': place + } + return render(request, 'rental/merci.html', context) + except IntegrityError: + form.errors['internal'] = "Une erreur interne est apparue. Merci de recommencer votre requête." + else: + form = ReservationForm() + context = {'form' : form} + return render(request, 'rental/reservation.html', context) -# def location(request, place_name): -# place = Place.objects.get(name=place_name) -# context = {'place' : place} -# return render(request, 'rental/detail_place.html', context) class Contact(TemplateView): template_name = 'rental/contact.html' -class Reserver(TemplateView): - template_name = 'rental/reservation.html' class Legal(TemplateView): template_name = 'rental/legal.html' -def about(request): - context = {} - return render(request, 'rental/about.html', context) + +class About(TemplateView): + template_name = 'rental/about.html' + + +def handler404(request, exception): + return render(request, 'store/404.html', status=404) + + +def handler500(request): + return render(request, 'store/500.html', status=500) diff --git a/villafleurie/urls.py b/villafleurie/urls.py index 92f1485..3784369 100644 --- a/villafleurie/urls.py +++ b/villafleurie/urls.py @@ -3,13 +3,16 @@ from django.urls import path from django.conf import settings from django.conf.urls import include, url from rental import views -# from django.contrib.flatpages import views as flat_views + urlpatterns = [ path('admin/', admin.site.urls), path('contact/', views.Contact.as_view(), name='contact'), - path('a-propos/', views.about, name='about'), - path('reservation/', views.Reserver.as_view(), name='reservation'), + path('a-propos/', views.About.as_view(), name='about'), + path('reservation/', views.reservation, name='reservation'), path('legal/', views.Legal.as_view(), name='legal'), path('', include('rental.urls', namespace='rental')), ] + +handler404 = 'rental.views.handler404' +handler500 = 'rental.views.handler500'