diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e99e36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc \ No newline at end of file diff --git a/account/forms.py b/account/forms.py index 5c75d96..0c3fb6c 100644 --- a/account/forms.py +++ b/account/forms.py @@ -5,8 +5,8 @@ from django import forms class LoginForm(forms.Form): # no need for max_length, let's not make heavyer things that can be lighter - username = forms.CharField(label="Nom d'utilisateur") - password = forms.CharField(label="Mot de passe", widget=forms.PasswordInput) + username = forms.CharField(label="", widget=forms.TextInput(attrs={'placeholder':'Identifiant'})) + password = forms.CharField(label="", widget=forms.PasswordInput(attrs={'placeholder':'Mot de passe'})) class InscriptionForm(forms.Form): username = forms.CharField(label="Nom d'utilisateur", min_length=settings.USERNAME_MIN_LENGTH, max_length=settings.USERNAME_MAX_LENGTH) diff --git a/account/views.py b/account/views.py index 3fa98ae..fd98bd3 100644 --- a/account/views.py +++ b/account/views.py @@ -1,18 +1,22 @@ +#-*- coding: utf-8 -*- + from django.shortcuts import render, redirect from django.contrib.auth import authenticate from django.contrib.auth.models import User from django.contrib.auth import login as a_login, logout as a_logout -from account.forms import * from django.core.urlresolvers import reverse -from django.core.validators import validate_email from django.conf import settings as s - +from django.http import JsonResponse +from django.http import Http404 +from account.forms import * from home.views import homepage - def login(request): - error = False - form = LoginForm() + """ + Login validation + Only accessible with ajax POST from menu and return json + """ + form = LoginForm(request.POST or None) if request.method == "POST": if form.is_valid(): username = form.cleaned_data["username"] @@ -20,20 +24,42 @@ def login(request): user = authenticate(username=username, password=password) if user: a_login(request, user) - return redirect(reverse(homepage)) + data = { + 'login':True + } else: - error = True - - return render(request, 'login.html', locals()) + data = { + 'login':False + } + if(User.objects.filter(username=username).exists()): + data['error'] = 'Mauvais mot de passe' + else: + data['error'] = 'Identifiant inconnu' + if('HTTP_X_REQUESTED_WITH' in request.META and request.META['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'): + return JsonResponse(data) + return render(request, 'account/login.html', locals()) + else: + #hack attempt, log it + print(request.POST) + elif request.method == "GET": + return render(request, 'account/login.html') + raise Http404 def logout(request): + """ + Logout user + with ajax POST from menu and reload page + """ a_logout(request) return redirect(reverse(homepage)) def signup(request): - error = False + """ + Signup user + with ajax POST from signup page and return json + """ form = InscriptionForm() if request.method == "POST": if form.is_valid(): @@ -42,25 +68,34 @@ def signup(request): username = form.cleaned_data["username"] email = form.cleaned_data["email"] cgu = form.cleaned_data["cgu"] - if( - username.length < s.USERNAME_MIN_LENGTH or username.length > s.USERNAME_MAX_LENGTH or - password.length < s.PASSWORD_MIN_LENGTH or password.length > s.PASSWORD_MAX_LENGTH or - password1 != password2 or cgu==False - ): - error = True - return render(request, 'signup.html', locals()) + if(password1 != password2): + data = { + 'registered':False, + 'error':"Les mots de passe ne sont pas identique !" + } + elif(User.objects.filter(username=username).exists()): + data = { + 'registered':False, + 'error':"Ce nom d'utilisateur est déjà utilisé !" + } + elif(User.objects.filter(email=email).exists()): + data = { + 'registered':False, + 'error':"Cette adresse email est déjà utilisé !" + } + else: + create_user(username, email, password1) + authenticate(username, password1) + data = { + 'registered':True + } - try: - validate_email(email) - except forms.ValidationError: - error = True - return render(request, 'signup.html', locals()) - - create_user(username, email, password1) - authenticate(username, password1) - return render(request, 'home.html', locals()) - - return render(request, 'signupt.html', locals()) + if('HTTP_X_REQUESTED_WITH' in request.META and request.META['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'): + return JsonResponse(data) + return render(request, 'account/signup.html', locals()) + elif request.method == "GET": + return render(request, 'account/signup.html', locals()) + raise Http404 def account(request): - return render(request, 'account.html') \ No newline at end of file + return render(request, 'account.html') diff --git a/home/forms.py b/home/forms.py new file mode 100644 index 0000000..531d474 --- /dev/null +++ b/home/forms.py @@ -0,0 +1,7 @@ +from django.conf import settings +from django import forms + +class ContactForm(forms.Form): + email = forms.EmailField(label="E-mail") + title = forms.CharField(label="Objet", min_length=settings.OBJECT_MIN_LENGTH, max_length=settings.OBJECT_MAX_LENGTH) + message = forms.CharField(label="Message", min_length=settings.MAILBODY_MIN_LENGTH, max_length=settings.MAILBODY_MAX_LENGTH) \ No newline at end of file diff --git a/home/urls.py b/home/urls.py index c5759d9..9b6d1f5 100644 --- a/home/urls.py +++ b/home/urls.py @@ -2,5 +2,7 @@ from django.conf.urls import url import home.views as v urlpatterns = [ - url(r'^$', v.homepage), + url(r'^$', v.homepage, name="homepage"), + url(r'^contact$', v.contact, name="contact"), + url(r'^articlê$', v.article, name="article") ] diff --git a/home/views.py b/home/views.py index 7016fa5..4e42abd 100644 --- a/home/views.py +++ b/home/views.py @@ -1,6 +1,39 @@ #-*- coding: utf-8 -*- -from django.shortcuts import render +from django.shortcuts import render, redirect +from django.contrib.auth import authenticate, get_user +from django.contrib.auth.models import User +from django.http import Http404 +from django.http import JsonResponse +from home.forms import * def homepage(request): - return render(request, 'home/homepage.html') \ No newline at end of file + """ + Render home page. + """ + return render(request, 'home/homepage.html', locals()) + +def contact(request): + """ + Form validation and contact page rendering. + """ + user = get_user(request) + form = ContactForm(request.POST or None, initial={'email': user.email if user.is_authenticated else ''}) + if request.method == "POST": + if form.is_valid(): + #TODO send email ? save into database ? + data = { + 'sent':True + } + if('HTTP_X_REQUESTED_WITH' in request.META and request.META['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'): + return JsonResponse(data) + return render(request, 'home/contact.html', locals()) + else: + #hack attempt, log it + print(request.POST) + elif request.method == "GET": + return render(request, 'home/contact.html', locals()) + raise Http404 + +def article(request): + return render(request, 'home/article.html') \ No newline at end of file diff --git a/planete_casio/context_processors.py b/planete_casio/context_processors.py new file mode 100644 index 0000000..e520530 --- /dev/null +++ b/planete_casio/context_processors.py @@ -0,0 +1,8 @@ +from django.conf import settings +from account.forms import LoginForm + +def menu(request): + dictionnaire = { + 'loginForm' : LoginForm(auto_id=False), + } + return dictionnaire \ No newline at end of file diff --git a/planete_casio/settings.py b/planete_casio/settings.py index d114006..dc041cd 100644 --- a/planete_casio/settings.py +++ b/planete_casio/settings.py @@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/1.9/ref/settings/ """ import os +from django.conf import global_settings # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -60,7 +61,7 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ - '/home/darks/web/planete_casio/templates/', + os.path.join(BASE_DIR, 'templates/'), ], 'APP_DIRS': True, 'OPTIONS': { @@ -69,6 +70,7 @@ TEMPLATES = [ 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', + 'planete_casio.context_processors.menu' ], }, }, @@ -136,16 +138,21 @@ APPEND_SLASH = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.9/howto/static-files/ -STATIC_URL = 'http://static.localhost/' # For dev css -# STATIC_URL = '/static/' # For Django admin css +# STATIC_URL = 'http://static.localhost/' # For dev css +STATIC_URL = '/sfiles/' # For Django admin css # STATIC_ROOT = '/home/web/planete_casio/static/' STATICFILES_DIRS = ( - "/home/web/planete_casio/sfiles/", + os.path.join(BASE_DIR, "sfiles"), ) + USERNAME_MIN_LENGTH = 3 USERNAME_MAX_LENGTH = 30 PASSWORD_MIN_LENGTH = 8 -PASSWORD_MAX_LENGTH = 72 # maximum number of characters for bcrypt \ No newline at end of file +PASSWORD_MAX_LENGTH = 72 # maximum number of characters for bcrypt +OBJECT_MIN_LENGTH = 3 +OBJECT_MAX_LENGTH = 255 +MAILBODY_MIN_LENGTH = 3 +MAILBODY_MAX_LENGTH = 10000 \ No newline at end of file diff --git a/planete_casio/urls.py b/planete_casio/urls.py index a65614e..36e34b7 100644 --- a/planete_casio/urls.py +++ b/planete_casio/urls.py @@ -16,14 +16,14 @@ Including another URLconf from django.conf import settings from django.conf.urls import url, include from django.contrib import admin -import account.views as v +import account.views as av urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^', include('home.urls')), - url(r'^forum/', include('forum.urls')), - url(r'^account/', include('account.urls')), - url(r'^login', v.login), - url(r'^logout', v.logout), - url(r'^signup', v.signup) + url(r'^forum/', include('forum.urls'), name="forum"), + url(r'^account/', include('account.urls'), name="account"), + url(r'^login', av.login, name="login"), + url(r'^logout', av.logout, name="logout"), + url(r'^signup', av.signup, name="signup") ] diff --git a/sfiles/css/container.css b/sfiles/css/container.css old mode 100755 new mode 100644 index bd1d3cf..4e2176b --- a/sfiles/css/container.css +++ b/sfiles/css/container.css @@ -2,7 +2,7 @@ margin-left: 60px; } -#container h1 { +/* #container h1 { margin-left: 5%; font-family: Raleway; font-size: 24px; font-weight: 200; color: #242424; @@ -12,75 +12,6 @@ margin-left: 5%; font-family: Raleway; font-size: 20px; font-weight: 200; color: #242424; -} - -article > div { - margin: 5px 15px; - text-align: justify; -} - -article .flex-container { - display: flex; -} - -article .flex-container > * { - flex-grow: 1; - max-width: 500px; - margin: 5px 10px; -} - -article .flex-container > * .more { - display: block; margin-left: 10px; - font-family: NotoSans; font-size: 12px; - color: #ba1203; - transition: .15s ease; -} -article .flex-container > * .more:hover { - padding-left: 1 5px; -} - -article p { - margin-bottom: 10px; -} +} */ -/* tiles */ -.tile-container { - display: flex; flex-wrap: wrap; - justify-content: space-around; - align-items: stretch; -} - -.tile-container > div { - flex-grow: 1; - min-width: 300px; - margin: 10px 15px; padding: 0 10px; - /*border: 1px solid #cccccc;*/ - border-radius: 3px; - box-shadow: 0px 1px 3px rgba(0, 0, 0, .3); -} - - -.tile-container table { - width: 100%; -} -.tile-container table td { - padding: 3px 5px; - display: flex; -} -.tile-container table input[type="text"], -.tile-container table input[type="date"] { - flex-grow: 1; - padding: 3px 10px; - border: 0; border-radius: 1px; - font-family: "Segoe UI", Helvetica, "Droid Sans", Arial,sans-serif; - box-shadow: 0 0 1px rgba(0, 0, 0, .4); transition: .15s ease; -} -.tile-container table input[type="text"]:focus, -.tile-container table input[type="date"]:focus { - box-shadow: 0 0 4px rgba(0, 102, 255, .9); -} -} -.tile-container table td:first-child { - /*text-align: right;*/ -} \ No newline at end of file diff --git a/sfiles/css/global.css b/sfiles/css/global.css old mode 100755 new mode 100644 index de78188..6fe5e6f --- a/sfiles/css/global.css +++ b/sfiles/css/global.css @@ -14,8 +14,8 @@ body { margin: 0; - background: #ffffff; - font-family: sans-serif; + background: #fbfbfb; + font-family: 'DejaVu Sans', sans-serif; } @@ -29,6 +29,9 @@ header { background: #f8f8fa; border-bottom: 1px solid #d0d0d0; } +header h1 { + font-family: Raleway; font-weight: 200; +} header svg { width: 24px; height: 24px; vertical-align: middle; @@ -69,6 +72,16 @@ header input[type="search"]:focus ~ a > svg > path { } +footer { + margin: 20px 10% 5px 10%; padding: 10px 0; + text-align: center; font-size: 11px; font-style: italic; + color: #a0a0a0; + border-top: 1px solid rgba(0, 0, 0, .1); +} +footer p { + margin: 3px 0; +} + /* links */ @@ -159,3 +172,18 @@ input[type="search"]:focus, input[type="password"]:focus { } + + +section { + margin: 10px 5%; +} + +section h1 { + border-bottom: 1px solid #a0a0a0; + font-family: Raleway; font-size: 24px; + font-weight: 200; color: #242424; +} + +section * { + transition: .15s ease; +} \ No newline at end of file diff --git a/sfiles/css/homepage.css b/sfiles/css/homepage.css new file mode 100644 index 0000000..b5eb580 --- /dev/null +++ b/sfiles/css/homepage.css @@ -0,0 +1,134 @@ +/* + home-title +*/ + +.home-title { + margin: 20px 0; padding: 10px 5%; + background: #bf1c11; box-shadow: 0 2px 2px rgba(0, 0, 0, .3); + border-top: 10px solid #ab170c; +} + +.home-title h1 { + margin-top: 0; + color: #ffffff; border-color: #ffffff; +} + +.home-title p { + margin-bottom: 0; text-align: justify; + color: #ffffff; +} + +.home-title a { + color: inherit; text-decoration: underline; +} + + +/* + pinned-content +*/ + +.home-pinned-content > div { + display: flex; justify-content: space-between; +} + +.home-pinned-content article { + flex-grow: 1; margin: 0 1px; padding: 0; + position: relative; + max-width: 250px; overflow: hidden; +} + +.home-pinned-content a { + display: block; +} + +.home-pinned-content img { + width: 100%; filter: blur(0px); +} + +.home-pinned-content article div { + position: absolute; bottom: 0; z-index: 3; + width: 90%; margin: 0; + padding: 30px 5% 10px 5%; + color: #ffffff; text-shadow: 1px 1px 0 rgba(0,0,0,.6); + background-image: linear-gradient(180deg,transparent 0,rgba(0,0,0,.7) 40px,rgba(0,0,0,.8)); +} + +.home-pinned-content h2 { + display: block; margin: 5px 0; + font-size: 18px; font-family: NotoSans; font-weight: 200; + line-height: 20px; +} + + +/* + home-articles +*/ + +.home-articles { + display: flex; justify-content: space-between; +} +.home-articles > div { + flex-grow: 1; max-width: 48%; +} +.home-articles h1 { + display: flex; justify-content: space-between; align-items: center; +} +.home-articles h1 a { + padding: 0; + font-family: NotoSans; font-size: 16px; + font-weight: 400; color: /*#015078*/ /*#bf1c11*/ #234d5f; +} + +.home-articles article { + padding: 10px; margin: 10px 0; display: flex; align-items: center; + background: #ffffff; border: 1px solid rgba(0, 0, 0, .2); +} +.home-articles article > img { + float: left; margin-right: 10px; flex-shrink: 0; +} +.home-articles article > img.screeshot { + width: 128px; height: 64px; +} +.home-articles article > div { + flex-shrink: 1; +} +.home-articles article h3 { + margin: 0; + color: #424242; font-weight: normal; +} +.home-articles p { + margin: 5px 0; + text-align: justify; + color: #808080; +} +.home-articles .metadata { + margin: 0; + color: #22292c; +} +.home-articles .metadata a { + color: #22292c; font-weight: 400; font-style: italic; +} + + +/* + hover rules +*/ + +.home-pinned-content a:hover img, +.home-pinned-content a:focus img { + filter: blur(3px); +} +.home-pinned-content a:hover div, +.home-pinned-content a:focus div { + padding: 200px 5% 10px 5%; + background-image: linear-gradient(180deg,transparent 0,rgba(0,0,0,.7) 40px,rgba(0,0,0,.8)); +} + +.home-articles h1 a:hover, +.home-articles h1 a:focus { + padding-right: 10px; +} +.home-articles article a:hover, +.home-articles article a:focus { + text-decoration: underline; +} diff --git a/sfiles/css/light.css b/sfiles/css/light.css old mode 100755 new mode 100644 index 5c76a91..ba80eb1 --- a/sfiles/css/light.css +++ b/sfiles/css/light.css @@ -253,4 +253,114 @@ header input[type="search"] { } #spotlight a:hover, header #spotlight a:focus { color: #404040; +} + + +/* Homepage */ + +section { + margin: 10px; +} +section h1 { + margin: 10px 0; + border-bottom: 1px solid #a0a0a0; + font-family: Raleway; font-size: 20px; + font-weight: 200; color: #242424; +} +section * { + transition: .15s ease; +} +.home-title { + margin: 20px 0; padding: 10px; + background: #bf1c11; box-shadow: 0 2px 2px rgba(0, 0, 0, .3); + border-top: 10px solid #ab170c; +} +.home-title h1 { + margin: 0; + color: #ffffff; border-color: #ffffff; +} +.home-title p { + margin-bottom: 0; text-align: justify; + color: #ffffff; font-size: 14px; +} +.home-title a { + color: inherit; text-decoration: underline; +} +#shoutbox { + display: none; +} +.home-pinned-content { + margin-top: 30px; +} +.home-pinned-content article { + margin: 5px 0; +} +.home-pinned-content article > a { + width: 100%; + display: flex; align-items: center; + text-decoration: none; +} +.home-pinned-content img { + flex-shrink: 0; + width: 100px; height: 100px; +} +.home-pinned-content article div { + flex-grow: 1; margin-left: 10px; +} +.home-pinned-content h2 { + margin: 0; + font-family: Raleway; font-size: 18px; + font-weight: 400; color: #242424; + text-decoration: underline; +} +.home-pinned-content span { + color: #000000; font-size: 14px; +} +.home-articles > div { + margin-top: 30px; +} +.home-articles article { + margin-bottom: 15px; + display: flex; align-items: center; +} +.home-articles article > img { + flex-shrink: 0; width: 128px; height: 64px; +} +.home-articles article > div { + margin-left: 5px; +} +.home-articles h1 { + display: flex; justify-content: space-between; align-items: center; +} +.home-articles h1 > a { + font-size: 13px; color: #666666; +} +.home-articles h3 { + margin: 0; + color: #424242; font-weight: normal; +} +.home-articles p { + margin: 5px 0; + text-align: justify; + color: #808080; font-size: 14px; +} + + +/* Notifications */ + +.alert { + display: none; +} + + +/* Footer */ + +footer { + margin: 20px 10% 5px 10%; padding: 10px 0; + text-align: center; font-size: 11px; font-style: italic; + color: #a0a0a0; + border-top: 1px solid rgba(0, 0, 0, .1); +} +footer p { + margin: 3px 0; } \ No newline at end of file diff --git a/sfiles/css/navbar.css b/sfiles/css/navbar.css old mode 100755 new mode 100644 index 465ecca..5dec525 --- a/sfiles/css/navbar.css +++ b/sfiles/css/navbar.css @@ -62,7 +62,7 @@ nav a:focus { display: flex; flex-direction: column; flex-grow: 1; align-items: center; justify-content: center; width: 100%; height: 100%; - -moz-transition: opacity .15s ease; /* because Chrome sucks */ + transition: opacity .15s ease; /* because Chrome sucks */ } #light-menu li > a > svg { @@ -75,12 +75,12 @@ nav a:focus { #light-menu li > a::after { content: attr(label); position: fixed; display: none; - padding: 4px 8px; margin-top: -28px; left: 63px; + padding: 4px 8px; /*margin-top: -28px;*/ left: 63px; font-family: NotoSans; border-radius: 3px; background: rgba(0, 0, 0, 0.9); } -#light-menu li > a:hover::after, -#light-menu li > a:focus::after { +#light-menu li:not(.opened) > a:hover::after, +#light-menu li:not(.opened) > a:focus::after { display: block; } @@ -96,21 +96,34 @@ nav a:focus { /* Overlay */ #menu { - position: fixed; left: 60px; z-index: 5; - width: 0; height: 100%; overflow-x: hidden; overflow-y: auto; + position: fixed; z-index: 5; + left: -240px; width: 300px; /* left-to-right animation */ + /*left: 60px; width: 0;*/ /* scroll animation */ + height: 100%; overflow-x: hidden; overflow-y: auto; font-family: NotoSans; font-size: 14px; background: #22292c; box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); - transition: .2s ease; + transition: 2s ease; } -/*@media all and (max-width: 1266px) { - #menu { - left: 30px; - } -}*/ #menu.opened { + left: 60px; /* left-to-right animation */ + /*width: 300px;*/ /* scroll animation */ +} + + +#menu.scroll-animation { + left: 60px; width: 0; +} +#menu.scroll-animation.opened { width: 300px; } +#menu.left-to-right-animation { + left: -240px; width: 300px; +} +#menu.left-to-right-animation.opened { + left: 60px; +} + #menu > div { width: 300px; @@ -169,14 +182,15 @@ nav a:focus { #menu form input { display: block; width: 80%; - margin: 5px auto; padding: 5px 10px; - font-size: 14px; + margin: 0 5%; padding: 5px 2%; + font-size: 14px; color: inherit; background: #e8e8e8; transition: background .15s ease; + border: none; } #menu form input:focus { background: #ffffff; } -#menu form input:first-child { +#menu form.login input:first-child { margin-bottom: 0; border-bottom: none; border-top-left-radius: 5px; -webkit-border-top-left-radius: 5px; @@ -185,7 +199,7 @@ nav a:focus { -webkit-border-top-right-radius: 5px; -moz-border-top-right-radius: 5px; } -#menu form input:nth-child(2) { +#menu form.login input:nth-child(2) { margin-top: 0; border-top: 1px solid #dddddd; border-bottom-left-radius: 5px; -webkit-border-bottom-left-radius: 5px; diff --git a/sfiles/css/responsive.css b/sfiles/css/responsive.css index bb9b435..c96f7a5 100644 --- a/sfiles/css/responsive.css +++ b/sfiles/css/responsive.css @@ -40,3 +40,14 @@ } } + +@media screen and (max-width: 1100px) { + .home-pinned-content article:nth-child(5) { + display: none; + } +} +@media screen and (max-width: 800px) { + .home-pinned-content article:nth-child(4) { + display: none; + } +} diff --git a/sfiles/css/shoutbox.css b/sfiles/css/shoutbox.css new file mode 100644 index 0000000..9725b29 --- /dev/null +++ b/sfiles/css/shoutbox.css @@ -0,0 +1,34 @@ +#shoutbox { + margin: 20px 5% 10px 5%; + /*box-shadow: 0 0 2px rgba(0, 0, 0, .4);*/ + background: #ffffff; + /*border: 1px solid #999999;*/ +} + +#shoutbox > div { + margin: 0; padding: 0; height: 125px; width: 100%; + overflow-y: scroll; border-bottom: 1px solid #999999; + border-radius: 5px 5px 0 0; + border: 1px solid #999999; +} +#shoutbox > input { + width: 100%; padding: 5px 0; + border-radius: 0 0 5px 5px; + border: 1px solid #999999; +} +#shoutbox > input:focus { + border-color: #a12222; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(161, 34, 34, 0.6); +} + +#shoutbox > div > div { + padding: 2px 10px; + border-bottom: 1px solid rgba(0, 0, 0, .3); + font-size: 11px; +} +#shoutbox > div > div:last-child { + border-bottom: none; +} +#shoutbox > div > div:hover { + background: #e0e0e0; +} \ No newline at end of file diff --git a/sfiles/scripts/contact.js b/sfiles/scripts/contact.js new file mode 100644 index 0000000..9161f94 --- /dev/null +++ b/sfiles/scripts/contact.js @@ -0,0 +1,3 @@ +function contact(response){ + alert(response) +} \ No newline at end of file diff --git a/sfiles/scripts/pc-utils.js b/sfiles/scripts/pc-utils.js new file mode 100644 index 0000000..f3dd880 --- /dev/null +++ b/sfiles/scripts/pc-utils.js @@ -0,0 +1,74 @@ +function setCookie(name, value) { + var end = new Date(); + end.setTime( end.getTime() + 3600 * 1000 ); + var str=name+"="+escape(value)+"; expires="+end.toGMTString()+"; path=/"; + document.cookie = str; +} +function getCookie(name) { + var debut = document.cookie.indexOf(name); + if( debut == -1 ) return null; + var end = document.cookie.indexOf( ";", debut+name.length+1 ); + if( end == -1 ) end = document.cookie.length; + return unescape( document.cookie.substring( debut+name.length+1, end ) ); +} + +function close_important(element) { + element.style.opacity = 0; + setTimeout(function(){ element.parentNode.removeChild(element); }, 200); +} + +/* + Send post ajax request to url defined in action. + Callback the function defined in the callback attribute from the submit type. +*/ +function ajaxWrapper(evt){ + evt.preventDefault(); + var elems = evt.target; + var params = ""; + // do not embed submit value (-1) + for(i = 0; i < elems.length-1; i++){ + if(params) params += "&"; + params += encodeURIComponent(elems[i].name)+"="+encodeURIComponent(elems[i].value); + } + const req = new XMLHttpRequest(); + req.open("POST", evt.target.action, true); + req.setRequestHeader('Content-Type',"application/x-www-form-urlencoded"); + req.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + req.onreadystatechange = function(){ + if(req.readyState == 4 && (req.status == 200 || req.status == 0)){ + var fn = window[elems[elems.length-1].getAttribute("callback")]; + if(typeof fn == 'function'){ + fn(req.responseText); + } + } + } + req.send(params); +} + +/* + Add event listener on submit for all form with class with-ajax. +*/ + +window.onload = function(){ + + var ele; + var elems = document.getElementsByClassName('with-ajax'); + for(i = 0; i < elems.length; i++){ + ele = elems[i]; + if(ele.addEventListener){ // Normal people + ele.addEventListener("submit", ajaxWrapper, false); + }else if(ele.attachEvent){ // Retarded user using IE + ele.attachEvent("onsubmit", ajaxWrapper); + } + } + + if(getCookie('pc_notif') == 'true') + document.getElementsByClassName('alert')[0].parentNode.removeChild(document.getElementsByClassName('alert')[0]); + if(getCookie('pc_notif_2') == 'true') + document.getElementsByClassName('alert')[0].parentNode.removeChild(document.getElementsByClassName('alert')[0]); + +} + +function login(response){ + alert(response); +} \ No newline at end of file diff --git a/templates/account/login.html b/templates/account/login.html index 0362eb0..53ff1ae 100644 --- a/templates/account/login.html +++ b/templates/account/login.html @@ -6,18 +6,19 @@

Formulaire de connexion

- {% if error %} -

Utilisateur inexistant ou mauvais de mot de passe.

+ {% if data != None and data.login == False %} +

{{ data.error }}

{% endif %} {% if user.is_authenticated %} Vous êtes connecté, {{ user.username }} ! {% else %} -
+ + {{ loginForm }} {% csrf_token %} - {{ form.as_p }} - +
+ Mot de passe oublié ? {% endif %}
diff --git a/templates/base.html b/templates/base.html index f728d03..2729e91 100644 --- a/templates/base.html +++ b/templates/base.html @@ -3,7 +3,7 @@ - {% block title %}Planète Casio : design template{% endblock %} + {% block title %}Planète Casio{% endblock %} @@ -12,13 +12,12 @@ -