Front event

This commit is contained in:
Jonas Legion 2021-06-22 11:24:30 +02:00
parent aa8333cd64
commit 8c3a13f0ba
29 changed files with 753 additions and 358 deletions

View File

@ -1 +1,45 @@
from django.contrib import admin
from django.contrib.admin import AdminSite
from solo.admin import SingletonModelAdmin
from BaseBillet.models import Configuration, Event, OptionGenerale
class StaffAdminSite(AdminSite):
site_header = "TiBillet Staff Admin"
site_title = "TiBillet Staff Admin"
site_url = '/'
def has_permission(self, request):
return request.user.is_superuser
staff_admin_site = StaffAdminSite(name='staff_admin')
########################################################################
staff_admin_site.register(Configuration, SingletonModelAdmin)
class EventAdmin(admin.ModelAdmin):
list_display = (
'name',
'reservations',
'datetime',
)
staff_admin_site.register(Event, EventAdmin)
class OptionGeneraleAdmin(admin.ModelAdmin):
list_display = (
'name',
'poids',
)
list_editable = (
'poids',
)
staff_admin_site.register(OptionGenerale, OptionGeneraleAdmin)

View File

View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class AuthbilletConfig(AppConfig):
name = 'AuthBillet'

View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

View File

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

View File

@ -0,0 +1,25 @@
# Generated by Django 2.2 on 2021-06-21 14:58
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Configuration',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('organisation', models.CharField(max_length=50)),
('short_description', models.CharField(max_length=250)),
],
options={
'abstract': False,
},
),
]

View File

@ -0,0 +1,28 @@
# Generated by Django 2.2 on 2021-06-21 15:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('BaseBillet', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='configuration',
name='facebook',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='configuration',
name='instagram',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='configuration',
name='twitter',
field=models.URLField(blank=True, null=True),
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 2.2 on 2021-06-21 15:36
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('BaseBillet', '0002_auto_20210621_1926'),
]
operations = [
migrations.CreateModel(
name='Event',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
('short_description', models.CharField(max_length=250)),
('long_description', models.TextField(blank=True, null=True)),
('datetime', models.DateTimeField()),
],
),
]

View File

@ -0,0 +1,35 @@
# Generated by Django 2.2 on 2021-06-21 16:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('BaseBillet', '0003_event'),
]
operations = [
migrations.AlterModelOptions(
name='event',
options={'ordering': ('datetime',), 'verbose_name': 'Evenement', 'verbose_name_plural': 'Evenements'},
),
migrations.AddField(
model_name='configuration',
name='adresse',
field=models.CharField(default='route de la joie', max_length=250),
preserve_default=False,
),
migrations.AddField(
model_name='configuration',
name='email',
field=models.EmailField(default='demo@demo.demo', max_length=254),
preserve_default=False,
),
migrations.AddField(
model_name='configuration',
name='phone',
field=models.CharField(default='-262 6 121212', max_length=20),
preserve_default=False,
),
]

View File

@ -0,0 +1,25 @@
# Generated by Django 2.2 on 2021-06-21 17:19
from django.db import migrations
import stdimage.models
import stdimage.validators
class Migration(migrations.Migration):
dependencies = [
('BaseBillet', '0004_auto_20210621_2059'),
]
operations = [
migrations.AddField(
model_name='configuration',
name='img',
field=stdimage.models.StdImageField(blank=True, null=True, upload_to='images/', validators=[stdimage.validators.MaxSizeValidator(1920, 1920)]),
),
migrations.AddField(
model_name='event',
name='img',
field=stdimage.models.StdImageField(blank=True, null=True, upload_to='images/', validators=[stdimage.validators.MaxSizeValidator(1920, 1920)]),
),
]

View File

@ -1,3 +1,116 @@
from django.db import models
# Create your models here.
from django.db.models.signals import post_save
from django.dispatch import receiver
from solo.models import SingletonModel
from django.utils.translation import ugettext_lazy as _
from stdimage import StdImageField
from stdimage.validators import MaxSizeValidator
class OptionGenerale(models.Model):
name = models.CharField(max_length=30)
poids = models.PositiveSmallIntegerField(default=0, verbose_name=_("Poids"))
def __str__(self):
return self.name
class Meta:
ordering = ('poids',)
verbose_name = _('Options Generales')
verbose_name_plural = _('Options Generales')
@receiver(post_save, sender=OptionGenerale)
def poids_option_generaler(sender, instance: OptionGenerale, created, **kwargs):
if created:
# poids d'apparition
if instance.poids == 0:
instance.poids = len(OptionGenerale.objects.all()) + 1
instance.save()
class Configuration(SingletonModel):
organisation = models.CharField(max_length=50)
short_description = models.CharField(max_length=250)
adresse = models.CharField(max_length=250)
phone = models.CharField(max_length=20)
email = models.EmailField()
twitter = models.URLField(blank=True, null=True)
facebook = models.URLField(blank=True, null=True)
instagram = models.URLField(blank=True, null=True)
img = StdImageField(upload_to='images/',
null=True, blank=True,
validators=[MaxSizeValidator(1920, 1920)],
variations={
'thumbnail': (1200, 1200),
}, delete_orphans=True)
mollie_api_key = models.CharField(max_length=50,
blank=True, null=True)
reservation_par_user_max = models.PositiveSmallIntegerField(default=6)
jauge_max = models.PositiveSmallIntegerField()
option_generale_radio = models.ManyToManyField(OptionGenerale,
blank=True,
related_name="radiobutton")
option_generale_checkbox = models.ManyToManyField(OptionGenerale,
blank=True,
related_name="checkbox")
class Event(models.Model):
name = models.CharField(max_length=200)
short_description = models.CharField(max_length=250)
long_description = models.TextField(blank=True, null=True)
datetime = models.DateTimeField()
img = StdImageField(upload_to='images/',
null=True, blank=True,
validators=[MaxSizeValidator(1920, 1920)],
variations={
'thumbnail': (500, 500),
}, delete_orphans=True)
reservations = models.PositiveSmallIntegerField(default=0)
def complet(self):
# TODO: Benchmarker et tester si c'est pas mieux dans template
if self.reservations >= Configuration.get_solo().jauge_max:
return True
else:
return False
class Meta:
ordering = ('datetime',)
verbose_name = _('Evenement')
verbose_name_plural = _('Evenements')
class reservation(models.Model):
event = models.ForeignKey(Event,
on_delete=models.CASCADE,
related_name="reservation")
ANNULEE, NON_VALIDEE, VALIDEE, PAYEE = 'NAN', 'NOV', 'VAL', 'PAY'
TYPE_CHOICES = [
(ANNULEE, _('Annulée')),
(NON_VALIDEE, _('Email non validé')),
(VALIDEE, _('Validée')),
(PAYEE, _('Payée')),
]
status = models.CharField(max_length=3, choices=TYPE_CHOICES, default=NON_VALIDEE,
verbose_name=_("Status de la réservation"))
qty = models.IntegerField()

View File

@ -3234,7 +3234,7 @@ input, select, textarea {
width: 100%;
height: 100%;
background-color: #212931;
background-image: url("../../images/overlay.png"), linear-gradient(0deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url("../../images/bg.jpg");
/*background-image: url("../../images/overlay.png"), linear-gradient(0deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url("../../images/bg.jpg");*/
background-size: auto, auto, 100% auto;
background-position: center, center, top center;
background-repeat: repeat, no-repeat, no-repeat;

View File

@ -19,7 +19,7 @@
width: 100%;
height: 100%;
background-color: _palette(wrapper-bg);
background-image: url('../../images/overlay.png'), linear-gradient(0deg, rgba(0,0,0,0.1), rgba(0,0,0,0.1)), url('../../images/bg.jpg');
//background-image: url('../../images/overlay.png'), linear-gradient(0deg, rgba(0,0,0,0.1), rgba(0,0,0,0.1)), url('../../images/bg.jpg');
background-size: auto, auto, 100% auto;
background-position: center, center, top center;
background-repeat: repeat, no-repeat, no-repeat;

View File

@ -0,0 +1,133 @@
{% block header %}
<!DOCTYPE HTML>
<!--
Massively by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
-->
<html lang="fr">
<head>
<title>{{ configuration.organisation }}</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
{% load static %}
<style>
#wrapper > .bg {
background-image: url("{% static 'html5up-massively/images/overlay.png' %}"), linear-gradient(0deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url("/media/{{ configuration.img }}");
}
</style>
<link rel="stylesheet" href="{% static 'html5up-massively/assets/css/main.css' %}"/>
{# <noscript>#}
{# <link rel="stylesheet" href="{% static 'html5up-massively/assets/css/noscript.css' %}"/>#}
{# </noscript>#}
</head>
{% endblock header %}
{% block content %}
{% endblock content %}
{% block footer %}
<!-- Footer -->
{# <footer>#}
{# <div class="pagination">#}
{# <!--<a href="#" class="previous">Prev</a>-->#}
{# <a href="#" class="page active">1</a>#}
{# <a href="#" class="page">2</a>#}
{# <a href="#" class="page">3</a>#}
{# <span class="extra">&hellip;</span>#}
{# <a href="#" class="page">8</a>#}
{# <a href="#" class="page">9</a>#}
{# <a href="#" class="page">10</a>#}
{# <a href="#" class="next">Next</a>#}
{# </div>#}
{# </footer>#}
</div>
<!-- Footer -->
<footer id="footer">
{# <section>#}
{# <form method="post" action="#">#}
{# <div class="fields">#}
{# <div class="field">#}
{# <label for="name">Name</label>#}
{# <input type="text" name="name" id="name"/>#}
{# </div>#}
{# <div class="field">#}
{# <label for="email">Email</label>#}
{# <input type="text" name="email" id="email"/>#}
{# </div>#}
{# <div class="field">#}
{# <label for="message">Message</label>#}
{# <textarea name="message" id="message" rows="3"></textarea>#}
{# </div>#}
{# </div>#}
{# <ul class="actions">#}
{# <li><input type="submit" value="Send Message"/></li>#}
{# </ul>#}
{# </form>#}
{# </section>#}
<section class="split contact">
<section class="alt">
<h3>Adresse</h3>
<p>{{ configuration.adresse }}</p>
</section>
<section>
<h3>Téléphone</h3>
<p>{{ configuration.phone }}</p>
</section>
<section>
<h3>Email</h3>
<p>{{ configuration.email }}</p>
</section>
<section>
<h3>Social</h3>
<ul class="icons alt">
{% if configuration.twitter %}
<li><a href="{{ configuration.twitter }}" class="icon brands alt fa-twitter"><span
class="label">Twitter</span></a>
</li>
{% endif %}
{% if configuration.facebook %}
<li><a href="{{ configuration.facebook }}" class="icon brands alt fa-facebook-f"><span
class="label">Facebook</span></a></li>
{% endif %}
{% if configuration.instagram %}
<li><a href="{{ configuration.instagram }}" class="icon brands alt fa-instagram"><span
class="label">Instagram</span></a></li>
{% endif %}
</ul>
</section>
</section>
</footer>
<!-- Copyright -->
<div id="copyright">
<ul>
<li><a href="https://tibillet.re">TiBillet</a></li>
<li>Design: <a href="https://html5up.net">HTML5 UP</a></li>
</ul>
</div>
</div>
<!-- Scripts -->
<script src="{% static 'html5up-massively/assets/js/jquery.min.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/jquery.scrollex.min.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/jquery.scrolly.min.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/browser.min.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/breakpoints.min.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/util.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/main.js' %}"></script>
</body>
</html>
{% endblock footer %}

View File

@ -27,7 +27,7 @@
<nav id="nav">
<ul class="links">
<li><a href="index.html">This is Massively</a></li>
<li><a href="generic.html">Generic Page</a></li>
<li><a href="event.html">Generic Page</a></li>
<li class="active"><a href="elements.html">Elements Reference</a></li>
</ul>
<ul class="icons">

View File

@ -0,0 +1,122 @@
{% extends "html5up-massively/base.html" %}
{% block content %}
<!-- Wrapper -->
<div id="wrapper">
<!-- Header -->
<header id="header">
<a href="/" class="logo">{{ configuration.organisation }}</a>
</header>
<!-- Nav -->
<nav id="nav">
<ul class="links">
<li class="active"><a href="index.html">Billetterie</a></li>
<li><a href="">Informations</a></li>
<li><a href="">Cashless</a></li>
</ul>
<ul class="icons">
{% if configuration.twitter %}
<li><a href="{{ configuration.twitter }}" class="icon brands fa-twitter"><span
class="label">Twitter</span></a></li>
{% endif %}
{% if configuration.facebook %}
<li><a href="{{ configuration.facebook }}" class="icon brands fa-facebook-f"><span
class="label">Facebook</span></a>
</li>
{% endif %}
{% if configuration.instagram %}
<li><a href="{{ configuration.instagram }}" class="icon brands fa-instagram"><span
class="label">Instagram</span></a>
</li>
{% endif %}
</ul>
</nav>
<!-- Main -->
<div id="main">
<!-- Post -->
<section class="post">
<header class="major">
<span class="date">{{ event.datetime.date }}<br/>{{ event.datetime.time }}</span>
<h1>{{ event.name }}</h1>
<p>{{ event.short_description }}</p>
</header>
<div class="image main"><img src="/media/{{ event.img }}" alt=""/></div>
<p>{{ event.long_description }}</p>
</section>
{% if not event.complet %}
<!-- Form -->
<form id="reservation" method="post" action="#">
{% csrf_token %}
<h2>RESERVEZ</h2>
<div class="row gtr-uniform">
<div class="col-6 col-12-xsmall">
<input type="text" name="nom" id="nom" value="" placeholder="Nom" required="True"/>
</div>
<div class="col-6 col-12-xsmall">
<input type="text" name="prenom" id="prenom" value="" placeholder="Prénom" required="True"/>
</div>
<div class="col-12 col-12-xsmall">
<input type="email" name="email" id="email" value="" placeholder="Email" required="True"/>
</div>
<div class="col-12 col-12-xsmall">
<input type="text" name="phone" id="phone" value="" placeholder="Téléphone" required="True"/>
</div>
<!-- Break -->
<div class="col-12">
<select name="qty" id="qty" required="True">
<option value="">- Quantitée -</option>
{# {% for nbr in configuration.reservation_max %}#}
<option value="{{ configuration.reservation_par_user_max }}">{{ configuration.reservation_par_user_max }}</option>
{# {% endfor %}#}
</select>
</div>
<!-- Break -->
{% for option_radio in configuration.option_generale_radio.all %}
<div class="col-4 col-12-small">
<input type="radio" id="{{ option_radio.name }}" name="radio_generale" value="{{ option_radio.pk }}">
<label for="{{ option_radio.name }}">{{ option_radio.name }}</label>
</div>
{% endfor %}
<!-- Break -->
{% for option_checkbox in configuration.option_generale_checkbox.all %}
<div class="col-6 col-12-small">
<input type="checkbox" id="{{ option_checkbox.name }}" name="{{ option_checkbox.name }}" value="{{ option_checkbox.pk }}">
<label for="{{ option_checkbox.name }}">{{ option_checkbox.name }}</label>
</div>
{% endfor %}
<!-- Break -->
{# <div class="col-12">#}
{# <textarea name="demo-message" id="demo-message" placeholder="Enter your message"#}
{# rows="6"></textarea>#}
{# </div>#}
<!-- Break -->
<div class="col-12">
<ul class="actions">
<li><input type="submit" value="validez" class="primary"/></li>
<li><input type="reset" value="Reset"/></li>
</ul>
</div>
</div>
</form>
<hr/>
{% else %}
<h2>COMPLET</h2>
{% endif %}
</div>
{% endblock content %}

View File

@ -1,127 +0,0 @@
<!DOCTYPE HTML>
<!--
Massively by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
-->
<html>
<head>
<title>Generic Page - Massively by HTML5 UP</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
{% load static %}
<link rel="stylesheet" href="{% static 'massively/assets/css/main.css' %}" />
<noscript><link rel="stylesheet" href={% static 'massively/assets/css/noscript.css' %} /></noscript>
</head>
<body class="is-preload">
<!-- Wrapper -->
<div id="wrapper">
<!-- Header -->
<header id="header">
<a href="index.html" class="logo">Massively</a>
</header>
<!-- Nav -->
<nav id="nav">
<ul class="links">
<li><a href="index.html">This is Massively</a></li>
<li class="active"><a href="generic.html">Generic Page</a></li>
<li><a href="elements.html">Elements Reference</a></li>
</ul>
<ul class="icons">
<li><a href="#" class="icon brands fa-twitter"><span class="label">Twitter</span></a></li>
<li><a href="#" class="icon brands fa-facebook-f"><span class="label">Facebook</span></a></li>
<li><a href="#" class="icon brands fa-instagram"><span class="label">Instagram</span></a></li>
<li><a href="#" class="icon brands fa-github"><span class="label">GitHub</span></a></li>
</ul>
</nav>
<!-- Main -->
<div id="main">
<!-- Post -->
<section class="post">
<header class="major">
<span class="date">April 25, 2017</span>
<h1>This is a<br />
Generic Page</h1>
<p>Aenean ornare velit lacus varius enim ullamcorper proin aliquam<br />
facilisis ante sed etiam magna interdum congue. Lorem ipsum dolor<br />
amet nullam sed etiam veroeros.</p>
</header>
<div class="image main"><img src="images/pic01.jpg" alt="" /></div>
<p>Donec eget ex magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque venenatis dolor imperdiet dolor mattis sagittis. Praesent rutrum sem diam, vitae egestas enim auctor sit amet. Pellentesque leo mauris, consectetur id ipsum sit amet, fergiat. Pellentesque in mi eu massa lacinia malesuada et a elit. Donec urna ex, lacinia in purus ac, pretium pulvinar mauris. Nunc lorem mauris, fringilla in aliquam at, euismod in lectus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur sapien risus, commodo eget turpis at, elementum convallis enim turpis, lorem ipsum dolor sit amet nullam.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis dapibus rutrum facilisis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam tristique libero eu nibh porttitor fermentum. Nullam venenatis erat id vehicula viverra. Nunc ultrices eros ut ultricies condimentum. Mauris risus lacus, blandit sit amet venenatis non, bibendum vitae dolor. Nunc lorem mauris, fringilla in aliquam at, euismod in lectus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In non lorem sit amet elit placerat maximus. Pellentesque aliquam maximus risus. Donec eget ex magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque venenatis dolor imperdiet dolor mattis sagittis. Praesent rutrum sem diam, vitae egestas enim auctor sit amet. Pellentesque leo mauris, consectetur id ipsum.</p>
</section>
</div>
<!-- Footer -->
<footer id="footer">
<section>
<form method="post" action="#">
<div class="fields">
<div class="field">
<label for="name">Name</label>
<input type="text" name="name" id="name" />
</div>
<div class="field">
<label for="email">Email</label>
<input type="text" name="email" id="email" />
</div>
<div class="field">
<label for="message">Message</label>
<textarea name="message" id="message" rows="3"></textarea>
</div>
</div>
<ul class="actions">
<li><input type="submit" value="Send Message" /></li>
</ul>
</form>
</section>
<section class="split contact">
<section class="alt">
<h3>Address</h3>
<p>1234 Somewhere Road #87257<br />
Nashville, TN 00000-0000</p>
</section>
<section>
<h3>Phone</h3>
<p><a href="#">(000) 000-0000</a></p>
</section>
<section>
<h3>Email</h3>
<p><a href="#">info@untitled.tld</a></p>
</section>
<section>
<h3>Social</h3>
<ul class="icons alt">
<li><a href="#" class="icon brands alt fa-twitter"><span class="label">Twitter</span></a></li>
<li><a href="#" class="icon brands alt fa-facebook-f"><span class="label">Facebook</span></a></li>
<li><a href="#" class="icon brands alt fa-instagram"><span class="label">Instagram</span></a></li>
<li><a href="#" class="icon brands alt fa-github"><span class="label">GitHub</span></a></li>
</ul>
</section>
</section>
</footer>
<!-- Copyright -->
<div id="copyright">
<ul><li>&copy; Untitled</li><li>Design: <a href="https://html5up.net">HTML5 UP</a></li></ul>
</div>
</div>
<!-- Scripts -->
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/jquery.scrollex.min.js"></script>
<script src="assets/js/jquery.scrolly.min.js"></script>
<script src="assets/js/browser.min.js"></script>
<script src="assets/js/breakpoints.min.js"></script>
<script src="assets/js/util.js"></script>
<script src="assets/js/main.js"></script>
</body>
</html>

View File

@ -1,230 +1,95 @@
<!DOCTYPE HTML>
<!--
Massively by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
-->
<html>
<head>
<title>Massively by HTML5 UP</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
{% load static %}
<link rel="stylesheet" href="{% static 'html5up-massively/assets/css/main.css' %}" />
<noscript><link rel="stylesheet" href="{% static 'html5up-massively/assets/css/noscript.css' %}" /></noscript>
</head>
<body class="is-preload">
{% extends "html5up-massively/base.html" %}
{% block content %}
<!-- Wrapper -->
<div id="wrapper" class="fade-in">
<!-- Wrapper -->
<div id="wrapper" class="fade-in">
<!-- Intro -->
<div id="intro">
<h1>This is<br />
Massively</h1>
<p>A free, fully responsive HTML5 + CSS3 site template designed by <a href="https://twitter.com/ajlkn">@ajlkn</a> for <a href="https://html5up.net">HTML5 UP</a><br />
and released for free under the <a href="https://html5up.net/license">Creative Commons license</a>.</p>
<ul class="actions">
<li><a href="#header" class="button icon solid solo fa-arrow-down scrolly">Continue</a></li>
</ul>
</div>
<!-- Intro -->
<div id="intro">
<h1>{{ configuration.organisation }}</h1>
<p>{{ configuration.short_description }}</p>
<ul class="actions">
<li><a href="#nav" class="button icon solid solo fa-arrow-down scrolly">Continuer</a></li>
</ul>
</div>
<!-- Header -->
<header id="header">
<a href="index.html" class="logo">Massively</a>
</header>
<!-- Header -->
<header id="header">
<a href="#nav" class="logo">{{ configuration.organisation }}</a>
</header>
<!-- Nav -->
<nav id="nav">
<ul class="links">
<li class="active"><a href="index.html">This is Massively</a></li>
<li><a href="generic.html">Generic Page</a></li>
<li><a href="elements.html">Elements Reference</a></li>
</ul>
<ul class="icons">
<li><a href="#" class="icon brands fa-twitter"><span class="label">Twitter</span></a></li>
<li><a href="#" class="icon brands fa-facebook-f"><span class="label">Facebook</span></a></li>
<li><a href="#" class="icon brands fa-instagram"><span class="label">Instagram</span></a></li>
<li><a href="#" class="icon brands fa-github"><span class="label">GitHub</span></a></li>
</ul>
</nav>
<!-- Nav -->
<nav id="nav">
<ul class="links">
<li class="active"><a href="index.html">Billetterie</a></li>
<li><a href="">Informations</a></li>
<li><a href="">Cashless</a></li>
</ul>
<ul class="icons">
{% if configuration.twitter %}
<li><a href="{{ configuration.twitter }}" class="icon brands fa-twitter"><span
class="label">Twitter</span></a></li>
{% endif %}
{% if configuration.facebook %}
<li><a href="{{ configuration.facebook }}" class="icon brands fa-facebook-f"><span
class="label">Facebook</span></a>
</li>
{% endif %}
{% if configuration.instagram %}
<li><a href="{{ configuration.instagram }}" class="icon brands fa-instagram"><span
class="label">Instagram</span></a>
</li>
{% endif %}
</ul>
</nav>
<!-- Main -->
<div id="main">
<!-- Main -->
<div id="main">
<!-- Featured Post -->
<article class="post featured">
<header class="major">
<span class="date">April 25, 2017</span>
<h2><a href="#">And this is a<br />
massive headline</a></h2>
<p>Aenean ornare velit lacus varius enim ullamcorper proin aliquam<br />
facilisis ante sed etiam magna interdum congue. Lorem ipsum dolor<br />
amet nullam sed etiam veroeros.</p>
</header>
<a href="#" class="image main"><img src="{% static 'html5up-massively/images/pic01.jpg' %}" alt="" /></a>
<ul class="actions special">
<li><a href="#" class="button large">Full Story</a></li>
</ul>
</article>
{% if first_event %}
<!-- Posts -->
<section class="posts">
<article>
<header>
<span class="date">April 24, 2017</span>
<h2><a href="#">Sed magna<br />
ipsum faucibus</a></h2>
</header>
<a href="#" class="image fit"><img src="{% static 'html5up-massively/images/pic02.jpg' %}" alt="" /></a>
<p>Donec eget ex magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque venenatis dolor imperdiet dolor mattis sagittis magna etiam.</p>
<ul class="actions special">
<li><a href="#" class="button">Full Story</a></li>
</ul>
</article>
<article>
<header>
<span class="date">April 22, 2017</span>
<h2><a href="#">Primis eget<br />
imperdiet lorem</a></h2>
</header>
<a href="#" class="image fit"><img src="{% static 'html5up-massively/images/pic03.jpg' %}" alt="" /></a>
<p>Donec eget ex magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque venenatis dolor imperdiet dolor mattis sagittis magna etiam.</p>
<ul class="actions special">
<li><a href="#" class="button">Full Story</a></li>
</ul>
</article>
<article>
<header>
<span class="date">April 18, 2017</span>
<h2><a href="#">Ante mattis<br />
interdum dolor</a></h2>
</header>
<a href="#" class="image fit"><img src="{% static 'html5up-massively/images/pic04.jpg' %}" alt="" /></a>
<p>Donec eget ex magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque venenatis dolor imperdiet dolor mattis sagittis magna etiam.</p>
<ul class="actions special">
<li><a href="#" class="button">Full Story</a></li>
</ul>
</article>
<article>
<header>
<span class="date">April 14, 2017</span>
<h2><a href="#">Tempus sed<br />
nulla imperdiet</a></h2>
</header>
<a href="#" class="image fit"><img src="{% static 'html5up-massively/images/pic05.jpg' %}" alt="" /></a>
<p>Donec eget ex magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque venenatis dolor imperdiet dolor mattis sagittis magna etiam.</p>
<ul class="actions special">
<li><a href="#" class="button">Full Story</a></li>
</ul>
</article>
<article>
<header>
<span class="date">April 11, 2017</span>
<h2><a href="#">Odio magna<br />
sed consectetur</a></h2>
</header>
<a href="#" class="image fit"><img src="{% static 'html5up-massively/images/pic06.jpg' %}" alt="" /></a>
<p>Donec eget ex magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque venenatis dolor imperdiet dolor mattis sagittis magna etiam.</p>
<ul class="actions special">
<li><a href="#" class="button">Full Story</a></li>
</ul>
</article>
<article>
<header>
<span class="date">April 7, 2017</span>
<h2><a href="#">Augue lorem<br />
primis vestibulum</a></h2>
</header>
<a href="#" class="image fit"><img src="{% static 'html5up-massively/images/pic07.jpg' %}" alt="" /></a>
<p>Donec eget ex magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque venenatis dolor imperdiet dolor mattis sagittis magna etiam.</p>
<ul class="actions special">
<li><a href="#" class="button">Full Story</a></li>
</ul>
</article>
</section>
<article class="post featured">
<header class="major">
<span class="date">{{ first_event.datetime.date }}<br/>{{ first_event.datetime.time }}</span>
<h2><a href="/event/{{ first_event.pk }}">{{ first_event.name }}</a></h2>
<p>{{ first_event.short_description }}</p>
</header>
<a href="#" class="image main"><img src="/media/{{ first_event.img }}" alt=""/></a>
<ul class="actions special">
<li><a href="/event/{{ first_event.pk }}" class="button large">RESERVEZ</a></li>
</ul>
</article>
<!-- Footer -->
<footer>
<div class="pagination">
<!--<a href="#" class="previous">Prev</a>-->
<a href="#" class="page active">1</a>
<a href="#" class="page">2</a>
<a href="#" class="page">3</a>
<span class="extra">&hellip;</span>
<a href="#" class="page">8</a>
<a href="#" class="page">9</a>
<a href="#" class="page">10</a>
<a href="#" class="next">Next</a>
</div>
</footer>
{% else %}
<!-- Featured Post -->
<article class="post featured">
<header class="major">
<span class="date">O_o</span>
<h2><a href="#">No event !</a></h2>
<p>Revenez un autre jour. Nous n'avons rien de prévu pour l'instant !</p>
</header>
</article>
</div>
{% endif %}
<!-- Footer -->
<footer id="footer">
<section>
<form method="post" action="#">
<div class="fields">
<div class="field">
<label for="name">Name</label>
<input type="text" name="name" id="name" />
</div>
<div class="field">
<label for="email">Email</label>
<input type="text" name="email" id="email" />
</div>
<div class="field">
<label for="message">Message</label>
<textarea name="message" id="message" rows="3"></textarea>
</div>
</div>
<ul class="actions">
<li><input type="submit" value="Send Message" /></li>
</ul>
</form>
</section>
<section class="split contact">
<section class="alt">
<h3>Address</h3>
<p>1234 Somewhere Road #87257<br />
Nashville, TN 00000-0000</p>
</section>
<section>
<h3>Phone</h3>
<p><a href="#">(000) 000-0000</a></p>
</section>
<section>
<h3>Email</h3>
<p><a href="#">info@untitled.tld</a></p>
</section>
<section>
<h3>Social</h3>
<ul class="icons alt">
<li><a href="#" class="icon brands alt fa-twitter"><span class="label">Twitter</span></a></li>
<li><a href="#" class="icon brands alt fa-facebook-f"><span class="label">Facebook</span></a></li>
<li><a href="#" class="icon brands alt fa-instagram"><span class="label">Instagram</span></a></li>
<li><a href="#" class="icon brands alt fa-github"><span class="label">GitHub</span></a></li>
</ul>
</section>
</section>
</footer>
<!-- Posts -->
<section class="posts">
<!-- Copyright -->
<div id="copyright">
<ul><li>&copy; Untitled</li><li>Design: <a href="https://html5up.net">HTML5 UP</a></li></ul>
</div>
</div>
{% for event in events %}
<article>
<header>
<span class="date">{{ event.datetime.date }}</span>
<h2><a href="/event/{{ event.pk }}">{{ event.name }}</a></h2>
</header>
<a href="#" class="image fit"><img src="/media/{{ event.img }}" alt=""/></a>
<p>{{ event.short_description }}</p>
<ul class="actions special">
<li><a href="/event/{{ event.pk }}" class="button">RESERVEZ</a></li>
</ul>
</article>
{% endfor %}
<!-- Scripts -->
<script src="{% static 'html5up-massively/assets/js/jquery.min.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/jquery.scrollex.min.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/jquery.scrolly.min.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/browser.min.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/breakpoints.min.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/util.js' %}"></script>
<script src="{% static 'html5up-massively/assets/js/main.js' %}"></script>
</section>
</body>
</html>
{% endblock content %}

View File

@ -3,5 +3,6 @@ from django.urls import include, path, re_path
from BaseBillet import views as base_view
urlpatterns = [
path('event/<str:id>', base_view.event.as_view()),
path('', base_view.index.as_view(), name="index"),
]

View File

@ -0,0 +1,22 @@
from rest_framework import serializers
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from BaseBillet.models import OptionGenerale, Configuration, Event
class ReservationValidator(serializers.Serializer):
nom = serializers.CharField(max_length=100, required=True)
prenom = serializers.CharField(max_length=100, required=True)
email = serializers.EmailField(required=True)
phone = serializers.CharField(max_length=100, required=True)
qty = serializers.IntegerField(required=True)
radio_generale = serializers.PrimaryKeyRelatedField(queryset=OptionGenerale.objects.all(), many=True)
def validate_qty(self, value):
configuration = Configuration.get_solo()
if value <= configuration.reservation_par_user_max :
return value
else :
raise serializers.ValidationError(_(f"Pas plus de {configuration.reservation_par_user_max} places en même temps."))

View File

@ -1,12 +1,75 @@
from django.shortcuts import render
from datetime import datetime
from django.shortcuts import render, redirect
# Create your views here.
from rest_framework import serializers, status
from rest_framework.generics import get_object_or_404
from rest_framework.permissions import AllowAny
from rest_framework.views import APIView
from rest_framework.response import Response
from django.utils.translation import ugettext_lazy as _
from BaseBillet.models import Configuration, Event
from BaseBillet.validator import ReservationValidator
class index(APIView):
permission_classes = [AllowAny]
def get(self, request):
return render(request, 'html5up-massively/index.html')
configuration = Configuration.get_solo()
events = Event.objects.filter(datetime__gt=datetime.now())
if len(events) > 0 :
first_event = events[0]
else :
first_event = None
context = {
'configuration': configuration,
'events': events[1:],
'first_event': first_event,
}
return render(request, 'html5up-massively/index.html', context=context)
class event(APIView):
permission_classes = [AllowAny]
def get(self, request, id):
event = get_object_or_404(Event, pk=id)
configuration = Configuration.get_solo()
context = {
'configuration': configuration,
'event': event,
}
return render(request, 'html5up-massively/event.html', context=context)
def post(self, request, id):
reservation_validator = ReservationValidator(data=request.data)
if reservation_validator.is_valid():
data_reservation = reservation_validator.validated_data
event = get_object_or_404(Event, pk=id)
configuration = Configuration.get_solo()
reste_place = configuration.jauge_max - event.reservations
if data_reservation.get('qty') > reste_place:
raise serializers.ValidationError(_(f"Il ne reste plus que {reste_place} places"))
context = {
'configuration': configuration,
'event': event,
'message': 'Merci de valider votre réservation sur votre boite mail',
}
return render(request, 'html5up-massively/event.html', context=context)
else:
print(f"validator.errors : {reservation_validator.errors}")
return Response(reservation_validator.errors, status=status.HTTP_400_BAD_REQUEST)

View File

@ -50,16 +50,22 @@ SHARED_APPS = (
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'django.contrib.staticfiles',
'django_extensions',
'Administration',
'MetaBillet',
'BaseBillet',
'ApiBillet',
'solo',
'stdimage',
)
TENANT_APPS = (
# The following Django contrib apps must be in TENANT_APPS
'django.contrib.contenttypes',
'BaseBillet',
'ApiBillet',
# your tenant-specific apps
)
@ -170,7 +176,6 @@ STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, "www", "media")
MEDIA_URL = '/media/'
# EMAIL
EMAIL_HOST = os.environ.get('EMAIL_HOST')
EMAIL_PORT = os.environ.get('EMAIL_PORT')

View File

@ -21,8 +21,8 @@ from Administration.admin_public import public_admin_site
urlpatterns = [
path('jet/', include('jet.urls', 'jet')), # Django JET URLS
re_path(r'^jet/dashboard/', include('jet.dashboard.urls', 'jet-dashboard')), # Django JET dashboard URLS
path('admin/', public_admin_site.urls, name="public_admin_url"),
re_path(r'^auth/', include('djoser.urls')),
path('admin/', public_admin_site.urls, name="public_admin_url"),
path('', include('MetaBillet.urls')),
# path('admin/', admin.site.urls, name="public_admin_url"),

View File

@ -15,14 +15,15 @@ Including another URLconf
"""
from django.contrib import admin
from django.urls import path, include, re_path
# from Administration.admin_public import public_admin_site
from django.conf.urls.static import static
from django.conf import settings
from Administration.admin_tenant import staff_admin_site
urlpatterns = [
path('jet/', include('jet.urls', 'jet')), # Django JET URLS
re_path(r'^jet/dashboard/', include('jet.dashboard.urls', 'jet-dashboard')), # Django JET dashboard URLS
path('admin/', admin.site.urls, name="public_admin_url"),
path('admin/', staff_admin_site.urls, name="staff_admin_site"),
re_path(r'^auth/', include('djoser.urls')),
re_path(r'^auth/', include('djoser.urls.authtoken')),
@ -30,4 +31,4 @@ urlpatterns = [
path('', include('BaseBillet.urls')),
# path('admin/', admin.site.urls, name="public_admin_url"),
]
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -50,8 +50,8 @@ RUN apt-get install -y --no-install-recommends postgresql-client
# RUN pip install django-silk
# RUN apt install openssh-client -y
# RUN pip install beautifulsoup4
# RUN pip install Pillow
# RUN pip install django-stdimage
RUN pip install Pillow
RUN pip install django-stdimage
# RUN pip install django-crispy-forms
# RUN pip install reportlab