Feedback et autres trucs

This commit is contained in:
Evarin 2017-04-20 23:04:07 +02:00
parent 9374a5f158
commit be57b976d2
18 changed files with 243 additions and 55 deletions

View file

@ -1,21 +1,27 @@
# coding: utf-8 # coding: utf-8
from tastypie.resources import ModelResource from tastypie.resources import ModelResource
from avisstage.models import Lieu from avisstage.models import Lieu, Stage, Normalien, StageMatiere
from tastypie.authentication import SessionAuthentication
from django.contrib.gis import geos from django.contrib.gis import geos
from tastypie import fields, utils
class LieuResource(ModelResource): class LieuResource(ModelResource):
stages = fields.ToManyField("avisstage.api.StageResource", "stages", use_in="detail", full=True)
class Meta: class Meta:
queryset = Lieu.objects.all() queryset = Lieu.objects.all()
resource_name = "lieu" resource_name = "lieu"
fields = ["nom", "pays", "coord", "type_lieu", "id"] fields = ["nom", "pays", "coord", "type_lieu", "id"]
authentication = SessionAuthentication()
def build_filters(self, filters=None, **kwargs): def build_filters(self, filters=None, **kwargs):
if filters is None: if filters is None:
filters = {} filters = {}
orm_filters = super(LieuResource, self).build_filters() orm_filters = super(LieuResource, self).build_filters(filters, **kwargs)
if "lng" in filters and "lat" in filters: if "lng" in filters and "lat" in filters:
lat = float(filters['lat']) lat = float(filters['lat'])
@ -40,5 +46,43 @@ class LieuResource(ModelResource):
bundle.data['distance'] = self.reference_point.distance(bundle.obj.coord) bundle.data['distance'] = self.reference_point.distance(bundle.obj.coord)
bundle.data["pays_nom"] = obj.get_pays_display() bundle.data["pays_nom"] = obj.get_pays_display()
bundle.data["type_lieu_nom"] = obj.get_type_lieu_display() bundle.data["type_lieu_nom"] = obj.get_type_lieu_display()
bundle.data["num_stages"] = obj.stages.filter(public=True).count()
return bundle return bundle
class StageResource(ModelResource):
class Meta:
queryset = Stage.objects.filter(public=True)
resource_name = "stage"
fields = ["sujet", "date_debut", "date_fin", "matieres", "id"]
authentication = SessionAuthentication()
def build_filters(self, filters=None, **kwargs):
if filters is None:
filters = {}
orm_filters = super(StageResource, self).build_filters(filters, **kwargs)
if "lieux" in filters:
flieux = map(int, filters['lieux'].split(','))
orm_filters['lieux__id__in'] = flieux
return orm_filters
def dehydrate(self, bundle):
bundle = super(StageResource, self).dehydrate(bundle)
obj = bundle.obj
bundle.data['auteur'] = obj.auteur.nom
bundle.data['thematiques'] = list(obj.thematiques.all().values_list("name", flat=True))
bundle.data['matieres'] = list(obj.matieres.all().values_list("nom", flat=True))
return bundle
class AuteurResource(ModelResource):
stages = fields.ToManyField("avisstage.api.StageResource", "stages", use_in="detail")
class Meta:
queryset = Normalien.objects.all()
resource_name = "profil"
fields = ["id", "nom", "stages"]
authentication = SessionAuthentication()

View file

@ -82,3 +82,7 @@ class LieuForm(forms.ModelForm):
model = Lieu model = Lieu
fields = ['nom', 'type_lieu', 'ville', 'pays', 'coord'] fields = ['nom', 'type_lieu', 'ville', 'pays', 'coord']
class FeedbackForm(forms.Form):
objet = forms.CharField(label="Objet", required=True)
message = forms.CharField(label="Message", required=True, widget=forms.widgets.Textarea())

View file

@ -5,8 +5,8 @@
$fond: #8fcc33; $fond: #8fcc33;
$barre: darken($fond, 10%); $barre: darken($fond, 10%);
$compl: #f99b20; $compl: #f99b20;
$jaune: #007afc; $jaune: #fff60a;
$vert: #09f7b0; $vert: #1a82dd;//09f7b0;
$rouge: #f70978; $rouge: #f70978;
$textfont: 'Dosis', sans-serif; $textfont: 'Dosis', sans-serif;
@ -584,6 +584,9 @@ div.as-results {
.hidden { .hidden {
display: none; display: none;
} }
.masked {
visibility: hidden;
}
} }
#avis_lieu_vide { #avis_lieu_vide {
@ -612,3 +615,15 @@ a.lieu-change {
width:100%; width:100%;
height: 600px; height: 600px;
} }
#feedback-button {
position:fixed;
left:0;
top:30%;
color:#fff;
z-index:4;
background: #000;
padding: 14px;
transform: rotateZ(90deg);
transform-origin: bottom left;
}

View file

@ -217,7 +217,7 @@ header h1 {
/* line 159, ../../sass/screen.scss */ /* line 159, ../../sass/screen.scss */
.stagelist li.stage-publie:before { .stagelist li.stage-publie:before {
content: "Publié"; content: "Publié";
background: #3af9c0; background: #419be9;
} }
/* line 163, ../../sass/screen.scss */ /* line 163, ../../sass/screen.scss */
.stagelist li.stage-ajout:before { .stagelist li.stage-ajout:before {
@ -231,7 +231,7 @@ article.stage {
} }
/* line 175, ../../sass/screen.scss */ /* line 175, ../../sass/screen.scss */
article.stage h2 { article.stage h2 {
background: #6ea3db; background: #ddda78;
color: #fff; color: #fff;
padding: 10px 20px; padding: 10px 20px;
margin: -20px; margin: -20px;
@ -353,13 +353,13 @@ article.stage section .plusmoins > div > div p {
} }
/* line 289, ../../sass/screen.scss */ /* line 289, ../../sass/screen.scss */
article.stage section .plusmoins .plus > div { article.stage section .plusmoins .plus > div {
background: #07df9f; background: #1775c6;
} }
/* line 292, ../../sass/screen.scss */ /* line 292, ../../sass/screen.scss */
article.stage section .plusmoins .plus:before { article.stage section .plusmoins .plus:before {
content: "Les +"; content: "Les +";
vertical-align: bottom; vertical-align: bottom;
color: #06c78d; color: #1567af;
} }
/* line 299, ../../sass/screen.scss */ /* line 299, ../../sass/screen.scss */
article.stage section .plusmoins .moins > div { article.stage section .plusmoins .moins > div {
@ -381,8 +381,8 @@ article.stage section .plusmoins .moins:before {
} }
/* line 318, ../../sass/screen.scss */ /* line 318, ../../sass/screen.scss */
.edit-box.public { .edit-box.public {
background: #cffdef; background: #cae3f9;
border: 1px solid #06ad7b; border: 1px solid #125b9b;
} }
/* line 323, ../../sass/screen.scss */ /* line 323, ../../sass/screen.scss */
.edit-box.prive { .edit-box.prive {
@ -657,13 +657,17 @@ div.as-results ul li.as-message {
.lieu-ui .hidden { .lieu-ui .hidden {
display: none; display: none;
} }
/* line 587, ../../sass/screen.scss */
.lieu-ui .masked {
visibility: hidden;
}
/* line 589, ../../sass/screen.scss */ /* line 592, ../../sass/screen.scss */
#avis_lieu_vide { #avis_lieu_vide {
display: none; display: none;
} }
/* line 593, ../../sass/screen.scss */ /* line 596, ../../sass/screen.scss */
a.lieu-change { a.lieu-change {
color: #fff; color: #fff;
background: #f99b20; background: #f99b20;
@ -676,14 +680,27 @@ a.lieu-change {
border-radius: 5px; border-radius: 5px;
margin-right: 7px; margin-right: 7px;
} }
/* line 605, ../../sass/screen.scss */ /* line 608, ../../sass/screen.scss */
a.lieu-change.ajout:before { a.lieu-change.ajout:before {
content: "+"; content: "+";
margin-right: 5px; margin-right: 5px;
} }
/* line 611, ../../sass/screen.scss */ /* line 614, ../../sass/screen.scss */
#stages-map { #stages-map {
width: 100%; width: 100%;
height: 600px; height: 600px;
} }
/* line 619, ../../sass/screen.scss */
#feedback-button {
position: fixed;
left: 0;
top: 30%;
color: #fff;
z-index: 4;
background: #000;
padding: 14px;
transform: rotateZ(90deg);
transform-origin: bottom left;
}

View file

@ -1,5 +1,5 @@
function SelectLieuWidget(STATIC_ROOT, API_LIEU, target, callback) { function SelectLieuWidget(STATIC_ROOT, API_LIEU, target, callback) {
var map, input, autocomplete; var map, input, autocomplete, map_el;
var $el = $(target); var $el = $(target);
var ui_el = $el.find('.lieu-ui'); var ui_el = $el.find('.lieu-ui');
var form_el = $el.find('form'); var form_el = $el.find('form');
@ -18,7 +18,7 @@ function SelectLieuWidget(STATIC_ROOT, API_LIEU, target, callback) {
closer.on("click", closeWidget).attr("href", "javascript:void(0);"); closer.on("click", closeWidget).attr("href", "javascript:void(0);");
$el.find(".window-bg").on("click", closeWidget); $el.find(".window-bg").on("click", closeWidget);
var map_el = $("<div>", {class: "map"}); map_el = $("<div>", {class: "map"});
input = $("<input>", input = $("<input>",
{type:"text", {type:"text",
placeholder:"Chercher un établissement..."}); placeholder:"Chercher un établissement..."});
@ -37,12 +37,21 @@ function SelectLieuWidget(STATIC_ROOT, API_LIEU, target, callback) {
autocomplete.addListener('place_changed', handlePlaceSearch); autocomplete.addListener('place_changed', handlePlaceSearch);
} }
function showMessage(message) {
content_el.find(".message").text(message);
}
function hideMessage() {
showMessage("");
}
function setLieuOrigine (lieu) { function setLieuOrigine (lieu) {
map.panTo(lieu.coord); map.panTo(lieu.coord);
lieuSurCarte(lieu, greenIcon); lieuSurCarte(lieu, greenIcon);
} }
function handleLieuOrigine(data) { function handleLieuOrigine(data) {
hideMessage();
lieux_db[data.id] = data; lieux_db[data.id] = data;
setLieuOrigine(data); setLieuOrigine(data);
askForSuggestions(data.coord); askForSuggestions(data.coord);
@ -52,16 +61,19 @@ function SelectLieuWidget(STATIC_ROOT, API_LIEU, target, callback) {
$el.addClass("visible").removeClass("ajout"); $el.addClass("visible").removeClass("ajout");
if(!ui_ready) if(!ui_ready)
initUI(); initUI();
hideMessage();
ui_el.removeClass("hidden"); ui_el.removeClass("hidden");
form_el.detach(); form_el.detach();
if (lieu_id === undefined) { if (lieu_id === undefined) {
$el.find("h3").text("Ajouter un lieu"); $el.find("h3").text("Ajouter un lieu");
map_el.addClass("masked");
} else { } else {
lieu_id = lieu_id * 1; lieu_id = lieu_id * 1;
$el.find("h3").text("Modifier le lieu"); $el.find("h3").text("Modifier le lieu");
if(lieux_db[lieu_id] === undefined) { if(lieux_db[lieu_id] === undefined) {
$.getJSON(API_LIEU + lieu_id + "/?format=json", $.getJSON(API_LIEU + lieu_id + "/?format=json",
handleLieuOrigine); handleLieuOrigine);
showMessage("Chargement...");
ui_el.addClass("hidden"); ui_el.addClass("hidden");
} else { } else {
handleLieuOrigine(lieux_db[lieu_id]); handleLieuOrigine(lieux_db[lieu_id]);
@ -150,6 +162,7 @@ function SelectLieuWidget(STATIC_ROOT, API_LIEU, target, callback) {
} }
function lieuSurCarte(data, icone) { function lieuSurCarte(data, icone) {
map_el.removeClass("masked");
// data : des données sur un lieu, sérialisé comme par tastypie // data : des données sur un lieu, sérialisé comme par tastypie
if(data.marqueur !== undefined) { if(data.marqueur !== undefined) {
if(map.hasLayer(data.marqueur)) if(map.hasLayer(data.marqueur))
@ -219,15 +232,16 @@ function SelectLieuWidget(STATIC_ROOT, API_LIEU, target, callback) {
form_el.serialize(), form_el.serialize(),
onLieuCreated); onLieuCreated);
form_el.detach(); form_el.detach();
content_el.append($("<p>").text("Envoi en cours...")); showMessage("Envoi en cours...");
return false; return false;
} }
function onLieuCreated(data) { function onLieuCreated(data) {
console.log(data); console.log(data);
if(data.success = false) if(data.success = false) {
content_el.find(".message").text("Erreur : "+data.errors);
content_el.append(form_el); content_el.append(form_el);
else { } else {
lieux_db.suggestion.id = data.id; lieux_db.suggestion.id = data.id;
callback(lieux_db.suggestion); callback(lieux_db.suggestion);
} }

View file

@ -1,4 +1,4 @@
{% load staticfiles %} {% load staticfiles avisstage_tags %}
<!doctype html> <!doctype html>
<html> <html>
<head> <head>
@ -24,14 +24,14 @@
<nav> <nav>
<ul id="menu"> <ul id="menu">
<li><a href="{% url 'avisstage:index' %}">Accueil</a></li> <li><a href="{% url 'avisstage:index' %}">Accueil</a></li>
{% if user.username %} {% if user.is_authenticated %}
<li><a href="{% url 'avisstage:perso' %}">Mes stages</a></li> <li><a href="{% url 'avisstage:perso' %}">Mes stages</a></li>
<li><a href="{% url 'avisstage:recherche' %}">Recherche</a></li> <li><a href="{% url 'avisstage:recherche' %}">Recherche</a></li>
{% endif %} {% endif %}
{% if user.is_staff %} {% if user.is_staff %}
<li><a href="{% url 'admin:index' %}">Administration</a></li> <li><a href="{% url 'admin:index' %}">Administration</a></li>
{% endif %} {% endif %}
{% if user.username %} {% if user.is_authenticated %}
<li><a href="{% url 'logout' %}"><span class="username">{{ user.username }}</span><br/> Déconnexion</a></li> <li><a href="{% url 'logout' %}"><span class="username">{{ user.username }}</span><br/> Déconnexion</a></li>
{% else %} {% else %}
<li><a href="{% url 'login' %}">Connexion</a></li> <li><a href="{% url 'login' %}">Connexion</a></li>
@ -40,27 +40,9 @@
</nav> </nav>
</header> </header>
{# BLOCK FEEDBACK #} {% if user.is_authenticated %}
{% if request.user.is_authenticated %} {% feedback_widget %}
<div id="feedback_win" class="win_bg">
<div class="win_centrer">
<div class="win_content">
<h2>Envoyer un avis sur le site<a class="win_close" href="javascript:showFeedback(false)">X</a></h2>
<form method="POST" action="{% url 'avisstage:feedback' %}?next={{ request.path|urlencode }}">
{% csrf_token %}
<p>Connecté en tant que {{ user.profil }}</p>
<p><label for="id_feedback-message">Commentaire :</label><textarea name="feedback-message" id="id_feedback-message"></textarea></p>
<input type="submit" />
</form>
</div>
</div>
</div>
<a id="feedback_btn" href="javascript:showFeedback(true)">
Feedback
</a>
{% endif %} {% endif %}
{# ENDBLOCK FEEDBACK #}
<section class="content"> <section class="content">
{% if messages %} {% if messages %}

View file

@ -1,6 +1,8 @@
{% extends "avisstage/base.html" %} {% extends "avisstage/base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}Profil de {{ object.nom }} - ExperiENS{% endblock %}
{% block content %} {% block content %}
<h1>Profil de {{ object.nom }}</h1> <h1>Profil de {{ object.nom }}</h1>
{% if object.user == user %} {% if object.user == user %}

View file

@ -1,6 +1,8 @@
{% extends "avisstage/base.html" %} {% extends "avisstage/base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{{ object.sujet }} - ExperiENS{% endblock %}
{% block extra_head %} {% block extra_head %}
<script src="{% static 'js/toc.min.js' %}" type="text/javascript"></script> <script src="{% static 'js/toc.min.js' %}" type="text/javascript"></script>
<script type="text/javascript" src="{% static "js/leaflet.js" %}"></script> <script type="text/javascript" src="{% static "js/leaflet.js" %}"></script>

View file

@ -12,8 +12,11 @@
<script type="text/javascript" src="{% static "js/select_lieu.js" %}"></script> <script type="text/javascript" src="{% static "js/select_lieu.js" %}"></script>
<script type="text/javascript"> <script type="text/javascript">
$(function() { $(function() {
// DATE FIELDS
$(".datepicker").datepicker({ dateFormat: 'dd/mm/yy' }); $(".datepicker").datepicker({ dateFormat: 'dd/mm/yy' });
// Process rich text fields
// RICH TEXT FIELDS
var txtr = $("textarea.tinymce"); var txtr = $("textarea.tinymce");
$.each(txtr, function(i, item) { $.each(txtr, function(i, item) {
var newitem = $("<div>", {"class":"tinymce"}).html(item.value) var newitem = $("<div>", {"class":"tinymce"}).html(item.value)
@ -30,7 +33,7 @@
language: "fr_FR", language: "fr_FR",
}); });
// Process select multiple fields // SELECT MULTIPLE FIELDS
var slts = $("select[multiple]"); var slts = $("select[multiple]");
var NULL_VAL = " "; var NULL_VAL = " ";
$.each(slts, function(i, item) { $.each(slts, function(i, item) {
@ -65,7 +68,7 @@
$item.remove(); $item.remove();
}); });
// Widget du choix du lieu // CHOIX DU LIEU
var lieu_select = new SelectLieuWidget( var lieu_select = new SelectLieuWidget(
"{{ STATIC_URL|escapejs }}", "{{ STATIC_URL|escapejs }}",
"{% url 'avisstage:api_dispatch_list' resource_name="lieu" api_name="v1" %}", "{% url 'avisstage:api_dispatch_list' resource_name="lieu" api_name="v1" %}",
@ -110,7 +113,7 @@
cnt.val(i_form+1); cnt.val(i_form+1);
$("#avis_lieu_container").append(dest_form); $("#avis_lieu_container").append(dest_form);
} else { } else {
// Changer le lieu // Changer un lieu existant
dest_form = $("#avis-lieux-"+lieu_focus); dest_form = $("#avis-lieux-"+lieu_focus);
dest_btn = lieux_liste.find("#change-lieux-"+lieu_focus); dest_btn = lieux_liste.find("#change-lieux-"+lieu_focus);
} }
@ -121,9 +124,9 @@
.val(lieu.id); .val(lieu.id);
lieu_select.closeWidget(); lieu_select.closeWidget();
} }
// TODO gérer le cas de l'actualisation du formulaire où le lieu affiché n'est plus le vrai lieu
// CLEANUP ON SENDING
// À l'envoi du formulaire
$("#stageform").submit(function() { $("#stageform").submit(function() {
$.each(txtr, function(i, item) { $.each(txtr, function(i, item) {
item.value = tinyMCE.get(item.fakeinput.attr("id")).getContent(); item.value = tinyMCE.get(item.fakeinput.attr("id")).getContent();

View file

@ -1,6 +1,8 @@
{% extends "avisstage/base.html" %} {% extends "avisstage/base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}ExperiENS - Partagez vos expériences de stage !{% endblock %}
{% block content %} {% block content %}
<div class="homeh1"> <div class="homeh1">
<h1>ExperiENS <span class="beta">beta</span></h1> <h1>ExperiENS <span class="beta">beta</span></h1>

View file

@ -1,6 +1,8 @@
{% extends "avisstage/base.html" %} {% extends "avisstage/base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}Espace personnel - ExperiENS{% endblock %}
{% block content %} {% block content %}
<h1>Mon espace personnel</h1> <h1>Mon espace personnel</h1>
<p><a href="{% url "avisstage:profil" user %}">{{ user.profil.nom }}</a> <a href="{% url "avisstage:profil_edit" %}">Modifier mes infos</a></p> <p><a href="{% url "avisstage:profil" user %}">{{ user.profil.nom }}</a> <a href="{% url "avisstage:profil_edit" %}">Modifier mes infos</a></p>

View file

@ -1,6 +1,9 @@
{% extends "avisstage/base.html" %} {% extends "avisstage/base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}Chercher un stage - ExperiENS{% endblock %}
{% block extra_head %} {% block extra_head %}
<script type="text/javascript" src="{% static "js/leaflet.js" %}"></script> <script type="text/javascript" src="{% static "js/leaflet.js" %}"></script>
<script type="text/javascript" src="{% static "js/leaflet.markercluster.js" %}"></script> <script type="text/javascript" src="{% static "js/leaflet.markercluster.js" %}"></script>
@ -34,7 +37,9 @@
var lieux = data.objects; var lieux = data.objects;
$.each(lieux, function(i, item) { $.each(lieux, function(i, item) {
var marqueur = L.marker(item.coord, {icon: greenIcon}); var marqueur = L.marker(item.coord, {icon: greenIcon});
marqueur.bindPopup("<h3>"+item.nom+"</h3>"); var txt = item.num_stages > 1 ? item.num_stages+" stages ici": "1 stage ici";
marqueur.bindPopup("<h3>"+item.nom+"</h3>"+
"<p>"+txt+"</p>");
marqueurs.addLayer(marqueur); marqueurs.addLayer(marqueur);
}); });
map.addLayer(marqueurs); map.addLayer(marqueurs);

View file

@ -0,0 +1,60 @@
{% load staticfiles %}
<div id="feedback_widget" class="window">
<script type="text/javascript">
$(function(){
function showFeedback() {
$("#feedback_widget").addClass("visible");
}
function hideFeedback() {
$("#feedback_widget").removeClass("visible");
}
function onFeedbackSent(data) {
if(data.success)
widget.find(".message").text("Message envoyé");
else {
widget.find(".message").text("Erreur : "+data);
}
}
$("#feedback-button").on("click", showFeedback);
var widget = $("#feedback_widget");
widget.find(".window-closer").on("click", hideFeedback);
widget.find(".window-bg").on("click", hideFeedback);
var form = widget.find("form");
form.on("submit", function(){
$.post(form.attr("action")+"?format=json", form.serialize(), onFeedbackSent);
form.detach();
widget.find(".message").text("Envoi en cours");
return false;
});
});
</script>
<div class="window-bg"></div>
<div class="window-content">
<a class="window-closer" href="javascript:void(0);"></a>
<h2>Donnez votre avis !</h2>
<div class="feedback-form">
<div class="message"></div>
<form action="{% url 'avisstage:feedback' %}" method="post" id="feedback">
{% csrf_token %}
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
<div class="field">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
<div class="input">
{{ field }}
{% if field.help_text %}
<p class="help_text">{{ field.help_text }}</p>
{% endif %}
</div>
</div>
{% endfor %}
<input type="submit" />
</form>
</div>
</div>
</div>
<a id="feedback-button" href="javascript:void(0);">Feedback</a>

View file

@ -5,6 +5,7 @@
<div class="window-content"> <div class="window-content">
<a class="window-closer"></a> <a class="window-closer"></a>
<h2>Choisir un lieu</h2> <h2>Choisir un lieu</h2>
<div class="message"></div>
<div class="lieu-ui"> <div class="lieu-ui">
</div> </div>
<div class="lieu-form">{% load staticfiles %} <div class="lieu-form">{% load staticfiles %}

View file

@ -1,6 +1,6 @@
from django import template from django import template
from avisstage.forms import LieuForm from avisstage.forms import LieuForm, FeedbackForm
register = template.Library() register = template.Library()
@ -8,3 +8,8 @@ register = template.Library()
def lieu_widget(): def lieu_widget():
form = LieuForm() form = LieuForm()
return {"form": form} return {"form": form}
@register.inclusion_tag('avisstage/templatetags/widget_feedback.html')
def feedback_widget():
form = FeedbackForm()
return {"form": form}

View file

@ -4,6 +4,8 @@ from tastypie.api import Api
v1_api = Api(api_name='v1') v1_api = Api(api_name='v1')
v1_api.register(api.LieuResource()) v1_api.register(api.LieuResource())
v1_api.register(api.StageResource())
v1_api.register(api.AuteurResource())
urlpatterns = [ urlpatterns = [
url(r'^$', views.index, name='index'), url(r'^$', views.index, name='index'),

View file

@ -9,9 +9,10 @@ from django.urls import reverse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from braces.views import LoginRequiredMixin from braces.views import LoginRequiredMixin
from django.http import JsonResponse, HttpResponseForbidden from django.http import JsonResponse, HttpResponseForbidden
from django.core.mail import send_mail
from avisstage.models import Normalien, Stage, Lieu, AvisLieu, AvisStage from avisstage.models import Normalien, Stage, Lieu, AvisLieu, AvisStage
from avisstage.forms import StageForm, LieuForm, AvisStageForm, AvisLieuForm from avisstage.forms import StageForm, LieuForm, AvisStageForm, AvisLieuForm, FeedbackForm
# Page d'accueil # Page d'accueil
def index(request): def index(request):
@ -123,9 +124,34 @@ def publier_stage(request, pk):
stage.public = False stage.public = False
stage.save() stage.save()
return redirect(reverse("avisstage:stage", kwargs={"pk": pk})) return redirect(reverse("avisstage:stage", kwargs={"pk": pk}))
@login_required
def recherche(request): def recherche(request):
return render(request, 'avisstage/recherche.html') return render(request, 'avisstage/recherche.html')
# FEEDBACK
@login_required
def feedback(request): def feedback(request):
return render(request, 'avisstage/feedback.html') if request.method == "POST":
form = FeedbackForm(request.POST)
if form.is_valid():
objet = form.cleaned_data['objet']
message = form.cleaned_data['message']
send_mail(
"[experiENS] "+ objet,
message,
request.user.username + "@clipper.ens.fr",
['champeno@clipper.ens.fr'],
fail_silently=False,
)
if request.GET.get("format", None) == "json":
return JsonResponse({"success": True})
return redirect(reverse("avisstage:index"))
else:
if request.GET.get("format", None) == "json":
return JsonResponse({"success": False,
"errors": form.errors})
else:
form = FeedbackForm()
return render(request, 'avisstage/formulaire/feedback.html', {"form": form})

View file

@ -22,3 +22,5 @@ MIDDLEWARE_CLASSES += (
SPATIALITE_LIBRARY_PATH = 'mod_spatialite' SPATIALITE_LIBRARY_PATH = 'mod_spatialite'
STATIC_ROOT = "/home/evarin/Bureau/experiENS/static/" STATIC_ROOT = "/home/evarin/Bureau/experiENS/static/"
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'