Commit 75162f0f48d8599787eb9e048f114444d19b0b48

Authored by Matheus Lins
2 parents fe3b3af0 841817e1

fixing conflits

amadeus/settings.py
@@ -79,6 +79,7 @@ TEMPLATES = [ @@ -79,6 +79,7 @@ TEMPLATES = [
79 'django.contrib.messages.context_processors.messages', 79 'django.contrib.messages.context_processors.messages',
80 80
81 'core.context_processors.notifications', 81 'core.context_processors.notifications',
  82 + 'courses.context_processors.courses',
82 ], 83 ],
83 }, 84 },
84 }, 85 },
app/templates/app/base.html
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 {% block menu_top %} 5 {% block menu_top %}
6 <ul class="nav navbar-nav"> 6 <ul class="nav navbar-nav">
7 <li class="active"> 7 <li class="active">
8 - <a href="#">Home</a> 8 + <a href="{% url 'home' %}">Home</a>
9 </li> 9 </li>
10 <li><a href="#contact">{% trans 'The Project' %}</a></li> 10 <li><a href="#contact">{% trans 'The Project' %}</a></li>
11 <li><a href="#contact">{% trans 'CCTE Group' %}</a></li> 11 <li><a href="#contact">{% trans 'CCTE Group' %}</a></li>
app/templates/home.html
@@ -64,7 +64,7 @@ @@ -64,7 +64,7 @@
64 {% block sidebar %} 64 {% block sidebar %}
65 <div class="panel panel-primary"> 65 <div class="panel panel-primary">
66 <div class="panel-heading"> 66 <div class="panel-heading">
67 - <img src="{{ user.image.url }}" id="img" class="img-rounded"> 67 + <img src="{{ user.image_url }}" id="img" class="img-rounded">
68 <p></p> 68 <p></p>
69 <div class="row"> 69 <div class="row">
70 <div class="col-xs-3 col-md-3"> 70 <div class="col-xs-3 col-md-3">
@@ -86,14 +86,24 @@ @@ -86,14 +86,24 @@
86 <li> <a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> 86 <li> <a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>
87 <li> <a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> 87 <li> <a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li>
88 <li> <a href="#">{% trans 'Pending Tasks' %}</a></li> 88 <li> <a href="#">{% trans 'Pending Tasks' %}</a></li>
89 - {% if user|has_role:'student' %}  
90 - <li> <a href="#">{% trans 'My courses' %}</a></li> 89 + {% if user|has_role:'student' and not user.is_staff %}
  90 + <li> <a href="{% url 'course:manage' %}">{% trans 'My courses' %}</a></li>
91 {% endif %} 91 {% endif %}
92 {% if user|has_role:'system_admin' %} 92 {% if user|has_role:'system_admin' %}
93 <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li> 93 <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li>
94 {% endif %} 94 {% endif %}
95 - {% if user|has_role:'system_admin, professor' %}  
96 - <li> <a href="{% url 'course:manage' %}">{% trans 'Manage Courses' %}</a></li> 95 + {% if user|has_role:'system_admin' or user|has_role:'professor' %}
  96 + <li>
  97 + <a href="#courses_list" class="accordion" data-toggle="collapse">{% trans 'Manage Courses' %}</a>
  98 +
  99 + <div id="courses_list" class="collapse">
  100 + <ul class="nav nav-pill nav-stacked accordion_list">
  101 + {% for course in courses_list %}
  102 + <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li>
  103 + {% endfor %}
  104 + </ul>
  105 + </div>
  106 + </li>
97 {% endif %} 107 {% endif %}
98 </ul> 108 </ul>
99 </div> 109 </div>
app/templates/home_student.html
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 <div class="panel-body"> 23 <div class="panel-body">
24 <ul class="nav nav-pills nav-stacked"> 24 <ul class="nav nav-pills nav-stacked">
25 <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> 25 <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li>
26 - <li><a href="javascript:void(0)">{% trans 'My Courses' %}</a></li> 26 + <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li>
27 <li><a href="javascript:void(0)">{% trans 'Google accounts' %}</a></li> 27 <li><a href="javascript:void(0)">{% trans 'Google accounts' %}</a></li>
28 </ul> 28 </ul>
29 </div> 29 </div>
app/templates/home_teacher_student_content.html
1 -{% load i18n %} 1 +{% load static i18n %}
2 2
3 {% for notification in objects %} 3 {% for notification in objects %}
4 <li {% if not notification.read %}class="not_read"{% endif %}> 4 <li {% if not notification.read %}class="not_read"{% endif %}>
5 <div class="avatar"> 5 <div class="avatar">
6 - <img src="{{ notification.user.image.url }}"> 6 + <img src="{{ notification.user.image_url }}">
7 </div> 7 </div>
8 <div class="bubble-container"> 8 <div class="bubble-container">
9 <div class="bubble"> 9 <div class="bubble">
@@ -43,8 +43,7 @@ class AppIndex(LoginRequiredMixin, LogMixin, ListView, NotificationMixin): @@ -43,8 +43,7 @@ class AppIndex(LoginRequiredMixin, LogMixin, ListView, NotificationMixin):
43 else: 43 else:
44 self.template_name = "home_teacher_student_content.html" 44 self.template_name = "home_teacher_student_content.html"
45 45
46 -  
47 - super(AppIndex, self).createNotification("teste", not_resource="home", resource_link="/register") 46 +
48 return self.response_class(request = self.request, template = self.template_name, context = context, using = self.template_engine, **response_kwargs) 47 return self.response_class(request = self.request, template = self.template_name, context = context, using = self.template_engine, **response_kwargs)
49 48
50 49
core/migrations/0009_auto_20160916_0126.py 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-09-16 04:26
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('core', '0008_resource_link'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.RenameField(
  16 + model_name='resource',
  17 + old_name='link',
  18 + new_name='url',
  19 + ),
  20 + ]
core/models.py
@@ -34,7 +34,7 @@ class Resource(models.Model): @@ -34,7 +34,7 @@ class Resource(models.Model):
34 34
35 name = models.CharField(_('Name'), max_length =100, unique=True) 35 name = models.CharField(_('Name'), max_length =100, unique=True)
36 created_date = models.DateField(_('Created Date'), auto_now_add=True) 36 created_date = models.DateField(_('Created Date'), auto_now_add=True)
37 - link = models.CharField(_('URL'), max_length =100, default="") 37 + url = models.CharField(_('URL'), max_length =100, default="")
38 38
39 39
40 class Meta: 40 class Meta:
core/static/css/base/amadeus.css
@@ -250,3 +250,15 @@ li.alert_li:hover{background-color:#eee} @@ -250,3 +250,15 @@ li.alert_li:hover{background-color:#eee}
250 .turn_off_alert{float:right;margin-bottom :1px} 250 .turn_off_alert{float:right;margin-bottom :1px}
251 a.alert_message{color : grey} 251 a.alert_message{color : grey}
252 a.alert_message:hover{color : grey} 252 a.alert_message:hover{color : grey}
  253 +
  254 +/*=================== Ailson - Please Don't touch*/
  255 +.breadcrumb .divider{
  256 + display: none;
  257 +}
  258 +
  259 +.accordion {
  260 + background: #c0c0c0;
  261 +}
  262 +.accordion_list {
  263 + background: #e0e0e0;
  264 +}
core/static/img/no_image.jpg 0 → 100644

2.99 KB

core/templates/base.html
@@ -48,7 +48,7 @@ @@ -48,7 +48,7 @@
48 <span class="icon-bar"></span> 48 <span class="icon-bar"></span>
49 <span class="icon-bar"></span> 49 <span class="icon-bar"></span>
50 </button> 50 </button>
51 - <a class="navbar-brand" href="javascript:void(0)"><img class="logo" src="{% static 'img/topo-amadeus.png' %}" alt="Logo"/></a> 51 + <a class="navbar-brand" href="{% url 'app:index' %}"><img class="logo" src="{% static 'img/topo-amadeus.png' %}" alt="Logo"/></a>
52 </div> 52 </div>
53 <div class="navbar-collapse collapse navbar-responsive-collapse"> 53 <div class="navbar-collapse collapse navbar-responsive-collapse">
54 <ul class="nav navbar-nav navbar-right notifications"> 54 <ul class="nav navbar-nav navbar-right notifications">
courses/context_processors.py 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +from .models import Course
  2 +
  3 +def courses(request):
  4 + if request.user.is_authenticated:
  5 + context = {}
  6 +
  7 + if request.user.is_staff:
  8 + context['courses_list'] = Course.objects.all()
  9 + else:
  10 + context['courses_list'] = Course.objects.filter(professors__in = [request.user])
  11 +
  12 + return context
  13 + else:
  14 + return request
0 \ No newline at end of file 15 \ No newline at end of file
courses/forms.py
  1 +
1 from django import forms 2 from django import forms
2 from django.utils.translation import ugettext_lazy as _ 3 from django.utils.translation import ugettext_lazy as _
3 from .models import Category, Course, Subject, Topic 4 from .models import Category, Course, Subject, Topic
@@ -17,6 +18,29 @@ class CategoryForm(forms.ModelForm): @@ -17,6 +18,29 @@ class CategoryForm(forms.ModelForm):
17 18
18 19
19 class CourseForm(forms.ModelForm): 20 class CourseForm(forms.ModelForm):
  21 + def clean_end_register_date(self):
  22 + init_register_date = self.data['init_register_date']
  23 + end_register_date = self.data['end_register_date']
  24 +
  25 + if init_register_date and end_register_date and end_register_date < init_register_date:
  26 + raise forms.ValidationError(_('The end date may not be before the start date.'))
  27 + return end_register_date
  28 +
  29 + def clean_init_date(self):
  30 + end_register_date = self.data['end_register_date']
  31 + init_date = self.data['init_date']
  32 +
  33 + if end_register_date and init_date and init_date <= end_register_date:
  34 + raise forms.ValidationError(_('The course start date must be after the end of registration.'))
  35 + return init_date
  36 +
  37 + def clean_end_date(self):
  38 + init_date = self.data['init_date']
  39 + end_date = self.data['end_date']
  40 +
  41 + if init_date and end_date and end_date < init_date:
  42 + raise forms.ValidationError(_('The end date may not be before the start date.'))
  43 + return end_date
20 44
21 # init_register_date = forms.DateField(widget=forms.DateField) 45 # init_register_date = forms.DateField(widget=forms.DateField)
22 # end_register_date = forms.DateField(widget=forms.DateField) 46 # end_register_date = forms.DateField(widget=forms.DateField)
@@ -53,6 +77,53 @@ class CourseForm(forms.ModelForm): @@ -53,6 +77,53 @@ class CourseForm(forms.ModelForm):
53 'category': _('Category which the course belongs'), 77 'category': _('Category which the course belongs'),
54 } 78 }
55 79
  80 + widgets = {
  81 + 'categoy': forms.Select(),
  82 + 'objectivies': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
  83 + 'content': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
  84 + }
  85 +
  86 +class UpdateCourseForm(CourseForm):
  87 + def __init__(self, *args, **kwargs):
  88 + super(UpdateCourseForm, self).__init__(*args, **kwargs)
  89 + self.fields["students"].required = False
  90 +
  91 + class Meta:
  92 + model = Course
  93 + fields = ('name', 'objectivies', 'content', 'max_students', 'init_register_date', 'end_register_date',
  94 + 'init_date', 'end_date', 'image', 'category','students',)
  95 + labels = {
  96 + 'name': _('Name'),
  97 + 'objectivies': _('Objectives'),
  98 + 'content': _('Content'),
  99 + 'max_students': _('Number of studets maximum'),
  100 + 'init_register_date': _('Course registration start date'),
  101 + 'end_register_date': _('Course registration end date'),
  102 + 'init_date': _('Course start date'),
  103 + 'end_date': _('Course end date'),
  104 + 'image': _('Image'),
  105 + 'category': _('Category'),
  106 + 'students': _('Student'),
  107 + }
  108 + help_texts = {
  109 + 'name': _('Course name'),
  110 + 'objectivies': _('Course objective'),
  111 + 'content': _('Course modules'),
  112 + 'max_students': _('Max number of students that a class can have'),
  113 + 'init_register_date': _('Date that starts the registration period of the course (dd/mm/yyyy)'),
  114 + 'end_register_date': _('Date that ends the registration period of the course (dd/mm/yyyy)'),
  115 + 'init_date': _('Date that the course starts (dd/mm/yyyy)'),
  116 + 'end_date': _('Date that the course ends (dd/mm/yyyy)'),
  117 + 'image': _('Representative image of the course'),
  118 + 'category': _('Category which the course belongs'),
  119 + 'students': _("Course's Students"),
  120 + }
  121 + widgets = {
  122 + 'categoy': forms.Select(),
  123 + 'objectivies': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
  124 + 'content': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
  125 + }
  126 +
56 class SubjectForm(forms.ModelForm): 127 class SubjectForm(forms.ModelForm):
57 128
58 class Meta: 129 class Meta:
courses/migrations/0013_auto_20160916_0001.py 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-09-16 03:01
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +import django.utils.timezone
  7 +
  8 +
  9 +class Migration(migrations.Migration):
  10 +
  11 + dependencies = [
  12 + ('courses', '0012_course_students'),
  13 + ]
  14 +
  15 + operations = [
  16 + migrations.AddField(
  17 + model_name='subject',
  18 + name='end_date',
  19 + field=models.DateField(default=django.utils.timezone.now, verbose_name='End of Subject Date'),
  20 + preserve_default=False,
  21 + ),
  22 + migrations.AddField(
  23 + model_name='subject',
  24 + name='init_date',
  25 + field=models.DateField(default=django.utils.timezone.now, verbose_name='Begin of Subject Date'),
  26 + preserve_default=False,
  27 + ),
  28 + ]
courses/migrations/0013_auto_20160916_0126.py 0 → 100644
@@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-09-16 04:26
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.conf import settings
  6 +from django.db import migrations, models
  7 +import django.db.models.deletion
  8 +
  9 +
  10 +class Migration(migrations.Migration):
  11 +
  12 + dependencies = [
  13 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  14 + ('core', '0009_auto_20160916_0126'),
  15 + ('courses', '0012_course_students'),
  16 + ]
  17 +
  18 + operations = [
  19 + migrations.CreateModel(
  20 + name='Activity',
  21 + fields=[
  22 + ('resource_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.Resource')),
  23 + ('create_date', models.DateTimeField(auto_now_add=True, verbose_name='Creation Date')),
  24 + ('limit_date', models.DateTimeField(verbose_name='Deliver Date')),
  25 + ('grade', models.IntegerField(verbose_name='grade')),
  26 + ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student', to=settings.AUTH_USER_MODEL, verbose_name='student')),
  27 + ],
  28 + bases=('core.resource',),
  29 + ),
  30 + migrations.CreateModel(
  31 + name='Link',
  32 + fields=[
  33 + ('resource_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.Resource')),
  34 + ('url_field', models.CharField(max_length=300, verbose_name='url')),
  35 + ],
  36 + bases=('core.resource',),
  37 + ),
  38 + migrations.AddField(
  39 + model_name='topic',
  40 + name='visible',
  41 + field=models.BooleanField(default=False, verbose_name='Visible'),
  42 + ),
  43 + migrations.AddField(
  44 + model_name='activity',
  45 + name='topic',
  46 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='topic', to='courses.Topic', verbose_name='Topic'),
  47 + ),
  48 + ]
courses/migrations/0014_merge_20160916_0255.py 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-09-16 05:55
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('courses', '0013_auto_20160916_0001'),
  12 + ('courses', '0013_auto_20160916_0126'),
  13 + ]
  14 +
  15 + operations = [
  16 + ]
courses/models.py
@@ -2,6 +2,7 @@ from django.utils.translation import ugettext_lazy as _ @@ -2,6 +2,7 @@ from django.utils.translation import ugettext_lazy as _
2 from django.db import models 2 from django.db import models
3 from autoslug.fields import AutoSlugField 3 from autoslug.fields import AutoSlugField
4 from users.models import User 4 from users.models import User
  5 +from core.models import Resource
5 6
6 class Category(models.Model): 7 class Category(models.Model):
7 8
@@ -47,6 +48,8 @@ class Subject(models.Model): @@ -47,6 +48,8 @@ class Subject(models.Model):
47 slug = AutoSlugField(_("Slug"),populate_from='name',unique=True) 48 slug = AutoSlugField(_("Slug"),populate_from='name',unique=True)
48 description = models.TextField(_('Description'), blank = True) 49 description = models.TextField(_('Description'), blank = True)
49 visible = models.BooleanField(_('Visible'), default = False) 50 visible = models.BooleanField(_('Visible'), default = False)
  51 + init_date = models.DateField(_('Begin of Subject Date'))
  52 + end_date = models.DateField(_('End of Subject Date'))
50 create_date = models.DateTimeField(_('Creation Date'), auto_now_add = True) 53 create_date = models.DateTimeField(_('Creation Date'), auto_now_add = True)
51 update_date = models.DateTimeField(_('Date of last update'), auto_now=True) 54 update_date = models.DateTimeField(_('Date of last update'), auto_now=True)
52 course = models.ForeignKey(Course, verbose_name = _('Course'), related_name="subjects") 55 course = models.ForeignKey(Course, verbose_name = _('Course'), related_name="subjects")
@@ -70,6 +73,7 @@ class Topic(models.Model): @@ -70,6 +73,7 @@ class Topic(models.Model):
70 update_date = models.DateTimeField(_('Date of last update'), auto_now=True) 73 update_date = models.DateTimeField(_('Date of last update'), auto_now=True)
71 subject = models.ForeignKey(Subject, verbose_name = _('Subject'), related_name="topics") 74 subject = models.ForeignKey(Subject, verbose_name = _('Subject'), related_name="topics")
72 owner = models.ForeignKey(User, verbose_name = _('Owner'), related_name="topics") 75 owner = models.ForeignKey(User, verbose_name = _('Owner'), related_name="topics")
  76 + visible = models.BooleanField(_('Visible'), default=False)
73 77
74 class Meta: 78 class Meta:
75 ordering = ('create_date','name') 79 ordering = ('create_date','name')
@@ -78,3 +82,21 @@ class Topic(models.Model): @@ -78,3 +82,21 @@ class Topic(models.Model):
78 82
79 def __str__(self): 83 def __str__(self):
80 return self.name 84 return self.name
  85 +
  86 +"""
  87 +It is one kind of possible resources available inside a Topic.
  88 +Activity is something that has a deadline and has to be delivered by the student
  89 +"""
  90 +class Activity(Resource):
  91 + create_date = models.DateTimeField(_('Creation Date'), auto_now_add = True)
  92 + topic = models.ForeignKey(Topic, verbose_name = _('Topic'), related_name="topic")
  93 + create_date = models.DateTimeField(_('Creation Date'), auto_now_add = True)
  94 + limit_date = models.DateTimeField(_('Deliver Date'))
  95 + student = models.ForeignKey(User, verbose_name = _('student'), related_name="student")
  96 + grade = models.IntegerField(_('grade'))
  97 +
  98 +"""
  99 +It is one kind of possible resources available inside a Topic.
  100 +"""
  101 +class Link(Resource):
  102 + url_field = models.CharField(_('url'), max_length= 300)
81 \ No newline at end of file 103 \ No newline at end of file
courses/permissions.py
@@ -30,3 +30,23 @@ def delete_subject(role, user, subject): @@ -30,3 +30,23 @@ def delete_subject(role, user, subject):
30 return True 30 return True
31 31
32 return False 32 return False
  33 +
  34 +@register_object_checker()
  35 +def update_course(role, user, course):
  36 + if (role == SystemAdmin):
  37 + return True
  38 +
  39 + if (user in course.professors.all()):
  40 + return True
  41 +
  42 + return False
  43 +
  44 +@register_object_checker()
  45 +def delete_course(role, user, course):
  46 + if (role == SystemAdmin):
  47 + return True
  48 +
  49 + if (user in course.professors.all()):
  50 + return True
  51 +
  52 + return False
courses/templates/course/create.html
1 -{% extends 'app/base.html' %} 1 +{% extends 'course/view.html' %}
2 2
3 {% load static i18n %} 3 {% load static i18n %}
4 {% load widget_tweaks %} 4 {% load widget_tweaks %}
@@ -10,16 +10,9 @@ @@ -10,16 +10,9 @@
10 </ol> 10 </ol>
11 {% endblock %} 11 {% endblock %}
12 12
13 -{% block sidebar %}  
14 - <div class="list-group">  
15 - <a href="{% url 'course:manage' %}" class="list-group-item">  
16 - {% trans 'Courses' %}  
17 - </a>  
18 - </div>  
19 -{% endblock %}  
20 -  
21 {% block content %} 13 {% block content %}
22 14
  15 +<<<<<<< HEAD
23 <form method="post" action="" enctype="multipart/form-data"> 16 <form method="post" action="" enctype="multipart/form-data">
24 {% csrf_token %} 17 {% csrf_token %}
25 {% for field in form %} 18 {% for field in form %}
@@ -46,4 +39,56 @@ @@ -46,4 +39,56 @@
46 <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" /> 39 <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />
47 </form> 40 </form>
48 <br clear="all" /> 41 <br clear="all" />
  42 +=======
  43 +</br>
  44 +<div class="card card-content">
  45 + <div class="card-body">
  46 + <form method="post" action="" enctype="multipart/form-data">
  47 + {% csrf_token %}
  48 + {% for field in form %}
  49 + <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput">
  50 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  51 + {% if field.auto_id == 'id_init_register_date' or field.auto_id == 'id_end_register_date' or field.auto_id == 'id_init_date' or field.auto_id == 'id_end_date'%}
  52 + <input type="date" class="form-control"name="{{field.name}}" value="{% if field.value.year %}{{field.value|date:'Y-m-d'}}{% else %}{{field.value}}{% endif %}" min="{{now|date:'Y-m-d'}}">
  53 + {% elif field.auto_id == 'id_image' %}
  54 + {% render_field field class='form-control' %}
  55 + <div class="input-group">
  56 + <input type="text" readonly="" class="form-control" placeholder="Choose your photo..."/>
  57 + <span class="input-group-btn input-group-sm">
  58 + <button type="button" class="btn btn-fab btn-fab-mini">
  59 + <i class="material-icons">attach_file</i>
  60 + </button>
  61 + </span>
  62 + </div>
  63 + {% else %}
  64 + {% render_field field class='form-control' %}
  65 + {% endif %}
  66 + <span class="help-block">{{ field.help_text }}</span>
  67 + {% if field.errors %}
  68 + <div class="row">
  69 + </br>
  70 + <div class="alert alert-danger alert-dismissible" role="alert">
  71 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  72 + <span aria-hidden="true">&times;</span>
  73 + </button>
  74 + <ul>
  75 + {% for error in field.errors %}
  76 + <li>{{ error }}</li>
  77 + {% endfor %}
  78 + </ul>
  79 + </div>
  80 + </div>
  81 + {% endif %}
  82 + </div>
  83 + {% endfor %}
  84 + <div class="row text-center">
  85 + <input type="submit" value="{% trans 'Create' %}" class="btn btn-primary" />
  86 + </div>
  87 + </form>
  88 + </div>
  89 +</div>
  90 +</br>
  91 +</br>
  92 +</br>
  93 +>>>>>>> 841817e1db11c57551cb8e21bf361e5bf6c9d982
49 {% endblock %} 94 {% endblock %}
courses/templates/course/delete.html
1 -{% extends 'app/base.html' %} 1 +{% extends 'course/view.html' %}
2 2
3 {% load static i18n %} 3 {% load static i18n %}
4 4
@@ -9,23 +9,15 @@ @@ -9,23 +9,15 @@
9 </ol> 9 </ol>
10 {% endblock %} 10 {% endblock %}
11 11
12 -{% block sidebar %}  
13 - <div class="list-group">  
14 - <a href="{% url 'course:manage' %}" class="list-group-item">  
15 - {% trans 'Courses' %}  
16 - </a>  
17 - <a href="{% url 'course:create' %}" class="list-group-item">  
18 - {% trans 'Create Course' %}  
19 - </a>  
20 - </div>  
21 -  
22 -{% endblock %}  
23 -  
24 {% block content %} 12 {% block content %}
25 - <form action="" method="post">  
26 - {% csrf_token %}  
27 - <p>{% trans 'Are you sure you want to delete the couse' %} "{{ object }}"?</p>  
28 - <input type="submit" class="btn btn-success btn-sm" value="{% trans 'Yes' %}" />  
29 - <a href="{% url 'course:manage' %}" class="btn btn-danger btn-sm">{% trans 'No' %}</a>  
30 - </form> 13 +<div class="panel panel-default">
  14 + <div class="panel-body">
  15 + <form action="" method="post">
  16 + {% csrf_token %}
  17 + <h2>{% trans 'Are you sure you want to delete the course' %} "{{course}}"?</h2>
  18 + <input type="submit" class="btn btn-raised btn-success btn-lg" value="{% trans 'Yes' %}" />
  19 + <a href="{% url 'course:view' course.slug%}" class="btn btn-raised btn-danger btn-lg">{% trans 'No' %}</a>
  20 + </form>
  21 + </div>
  22 +</div>
31 {% endblock %} 23 {% endblock %}
courses/templates/course/index.html
@@ -54,7 +54,11 @@ @@ -54,7 +54,11 @@
54 {% for course in courses %} 54 {% for course in courses %}
55 <div class="row well well-inverse"> 55 <div class="row well well-inverse">
56 <div class="col-md-2"> 56 <div class="col-md-2">
  57 + {% if course.image %}
57 <img src="{{ course.image.url }}" class="img-responsive" /> 58 <img src="{{ course.image.url }}" class="img-responsive" />
  59 + {% else %}
  60 + <img src="" class="img-responsive" />
  61 + {% endif %}
58 </div> 62 </div>
59 <div class="col-md-10"> 63 <div class="col-md-10">
60 <div class="row"> 64 <div class="row">
courses/templates/course/update.html
1 -{% extends 'app/base.html' %} 1 +{% extends 'course/view.html' %}
2 2
3 {% load static i18n %} 3 {% load static i18n %}
4 {% load widget_tweaks %} 4 {% load widget_tweaks %}
5 5
6 {% block breadcrumbs %} 6 {% block breadcrumbs %}
7 <ol class="breadcrumb"> 7 <ol class="breadcrumb">
8 - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>  
9 - <li class="active">{% trans 'Edit Course' %}</li> 8 + <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>
  9 + <li class="active">{% trans 'Edit Course' %}</li>
10 </ol> 10 </ol>
11 {% endblock %} 11 {% endblock %}
12 -  
13 -{% block sidebar %}  
14 - <div class="list-group">  
15 - <a href="{% url 'course:manage' %}" class="list-group-item">  
16 - {% trans 'Courses' %}  
17 - </a>  
18 - <a href="{% url 'course:manage_mods' course.slug %}" class="list-group-item">  
19 - {% trans 'Manage Modules' %}  
20 - </a>  
21 - <a href="#" class="list-group-item">  
22 - {% trans 'Participants' %}  
23 - </a>  
24 - </div>  
25 -{% endblock %}  
26 -  
27 {% block content %} 12 {% block content %}
28 - <div class="alert alert-info alert-dismissible" role="alert">  
29 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
30 - <span aria-hidden="true">&times;</span>  
31 - </button>  
32 - <p>{% trans 'All fields are required' %}</p>  
33 - </div>  
34 13
35 - <form method="post" action="" enctype="multipart/form-data">  
36 - {% csrf_token %}  
37 - {% for field in form %}  
38 - <div class="form-group{% if form.has_error %} has-error {% endif %}">  
39 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
40 - {% render_field field class='form-control input-sm' %}  
41 - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>  
42 - {% if field.errors.length > 0 %}  
43 - <div class="alert alert-danger alert-dismissible" role="alert">  
44 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
45 - <span aria-hidden="true">&times;</span>  
46 - </button>  
47 - <ul>  
48 - {% for error in field.errors %}  
49 - <li>{{ error }}</li>  
50 - {% endfor %}  
51 - </ul> 14 +</br>
  15 +<div class="card card-content">
  16 + <div class="card-body">
  17 + <form method="post" action="" enctype="multipart/form-data">
  18 + {% csrf_token %}
  19 + {% for field in form %}
  20 + <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput">
  21 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  22 + {% if field.auto_id == 'id_init_register_date' or field.auto_id == 'id_end_register_date' or field.auto_id == 'id_init_date' or field.auto_id == 'id_end_date'%}
  23 + <input type="date" class="form-control"name="{{field.name}}" value="{% if field.value.year %}{{field.value|date:'Y-m-d'}}{% else %}{{field.value}}{% endif %}" min="{{now|date:'Y-m-d'}}">
  24 + {% elif field.auto_id == 'id_image' %}
  25 + {% render_field field class='form-control' %}
  26 + <div class="input-group">
  27 + <input type="text" readonly="" class="form-control" placeholder="Choose your photo..."/>
  28 + <span class="input-group-btn input-group-sm">
  29 + <button type="button" class="btn btn-fab btn-fab-mini">
  30 + <i class="material-icons">attach_file</i>
  31 + </button>
  32 + </span>
  33 + </div>
  34 + {% else %}
  35 + {% render_field field class='form-control' %}
  36 + {% endif %}
  37 + <span class="help-block">{{ field.help_text }}</span>
  38 + {% if field.errors %}
  39 + <div class="row">
  40 + </br>
  41 + <div class="alert alert-danger alert-dismissible" role="alert">
  42 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  43 + <span aria-hidden="true">&times;</span>
  44 + </button>
  45 + <ul>
  46 + {% for error in field.errors %}
  47 + <li>{{ error }}</li>
  48 + {% endfor %}
  49 + </ul>
  50 + </div>
52 </div> 51 </div>
  52 + {% endif %}
53 </div> 53 </div>
54 - {% endif %} 54 + {% endfor %}
  55 + <div class="row text-center">
  56 + <input type="submit" value="{% trans 'Update' %}" class="btn btn-primary" />
55 </div> 57 </div>
56 - {% endfor %}  
57 - <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />  
58 - </form>  
59 - <br clear="all" /> 58 + </form>
  59 + </div>
  60 +</div>
  61 +</br>
  62 +</br>
  63 +</br>
60 {% endblock %} 64 {% endblock %}
courses/templates/course/view.html
@@ -15,9 +15,24 @@ @@ -15,9 +15,24 @@
15 {% endblock %} 15 {% endblock %}
16 16
17 {% block sidebar %} 17 {% block sidebar %}
18 -<div class="panel panel-primary navigation"> 18 +<div class="panel panel-primary">
19 <div class="panel-heading"> 19 <div class="panel-heading">
20 - <h5>{% trans "Menu" %}</h5> 20 + <img src="{{ user.image.url }}" id="img" class="img-circle img-responsive">
  21 + </br>
  22 + <div class="row">
  23 + <div class="col-xs-3 col-md-3">
  24 + <i class="fa fa-facebook-official fa-2x" aria-hidden="true"></i>
  25 + </div>
  26 + <div class="col-xs-3 col-md-3">
  27 + <i class="fa fa-twitter fa-2x" aria-hidden="true"></i>
  28 + </div>
  29 + <div class="col-xs-3 col-md-3">
  30 + <i class="fa fa-linkedin-square fa-2x" aria-hidden="true"></i>
  31 + </div>
  32 + <div class="col-xs-3 col-md-3">
  33 + <i class="fa fa-google-plus-official fa-2x" aria-hidden="true"></i>
  34 + </div>
  35 + </div>
21 </div> 36 </div>
22 <div class="panel-body"> 37 <div class="panel-body">
23 <ul class="nav nav-pills nav-stacked"> 38 <ul class="nav nav-pills nav-stacked">
@@ -28,7 +43,7 @@ @@ -28,7 +43,7 @@
28 </div> 43 </div>
29 </div> 44 </div>
30 {% if courses.count > 0 %} 45 {% if courses.count > 0 %}
31 -<div class="panel panel-primary navigation"> 46 +<div class="panel panel-primary">
32 <div class="panel-heading"> 47 <div class="panel-heading">
33 <h5>{% trans "Courses" %}</h5> 48 <h5>{% trans "Courses" %}</h5>
34 </div> 49 </div>
@@ -49,22 +64,24 @@ @@ -49,22 +64,24 @@
49 <div class="panel panel-info"> 64 <div class="panel panel-info">
50 <div class="panel-heading"> 65 <div class="panel-heading">
51 <div class="row"> 66 <div class="row">
52 -<div class="col-md-10"> 67 + <a href="{% url 'course:view_subject' subject.slug %}">
  68 + <div class="col-md-10">
53 69
54 - <h3 class="panel-title"><a href="{% url 'course:view_subject' subject.slug %}"></a>{{subject}}</h3> 70 + <h3 class="panel-title">{{subject}}</h3>
55 71
56 - </div>  
57 - <div class="col-md-2 text-right">  
58 - {% if user|has_role:'professor, system_admin' %}  
59 - <a href="{% url 'course:update_subject' subject.slug %}" style="padding: 3px; margin: 3px;" class="btn btn-sm btn-default">  
60 - <span class="glyphicon glyphicon-edit"></span>  
61 - </a>  
62 - <a href="{% url 'course:delete_subject' subject.slug %}" style="padding: 3px; margin: 3px;" class="btn btn-sm btn-danger">  
63 - <span class="glyphicon glyphicon-trash"></span>  
64 - </a>  
65 - {% endif %}  
66 - </div>  
67 -</div> 72 + </div>
  73 + </a>
  74 + <div class="col-md-2 text-right">
  75 + {% if user|has_role:'professor, system_admin' %}
  76 + <a href="{% url 'course:update_subject' subject.slug %}" style="padding: 3px; margin: 3px;" class="btn btn-sm btn-default">
  77 + <span class="glyphicon glyphicon-edit"></span>
  78 + </a>
  79 + <a href="{% url 'course:delete_subject' subject.slug %}" style="padding: 3px; margin: 3px;" class="btn btn-sm btn-danger">
  80 + <span class="glyphicon glyphicon-trash"></span>
  81 + </a>
  82 + {% endif %}
  83 + </div>
  84 + </div>
68 </div> 85 </div>
69 <div class="panel-body"> 86 <div class="panel-body">
70 <p><b>{% trans "Professor" %}: </b>{% for professor in subject.professors.all %}{% if not forloop.first %},{% endif %} 87 <p><b>{% trans "Professor" %}: </b>{% for professor in subject.professors.all %}{% if not forloop.first %},{% endif %}
@@ -77,10 +94,10 @@ @@ -77,10 +94,10 @@
77 </p> 94 </p>
78 <div class="row"> 95 <div class="row">
79 <div class="col-xs-6 col-md-6"> 96 <div class="col-xs-6 col-md-6">
80 - {# <p><b>{% trans "Begining" %}: </b>{{subject.init_date}}</p>#} 97 + <p><b>{% trans "Begining" %}: </b>{{subject.init_date}}</p>
81 </div> 98 </div>
82 <div class="col-xs-6 col-md-6"> 99 <div class="col-xs-6 col-md-6">
83 - {# <p><b>End: </b>23/08/2019</p>#} 100 + <p><b>{% trans "End" %}: </b>{{subject.end_date}}</p>
84 </div> 101 </div>
85 </div> 102 </div>
86 </div> 103 </div>
@@ -90,5 +107,12 @@ @@ -90,5 +107,12 @@
90 107
91 108
92 {% block rightbar %} 109 {% block rightbar %}
93 - 110 +<div class="panel panel-warning">
  111 + <div class="panel-heading">
  112 + <h3 class="panel-title">{% trans "Pending Stuffs" %}</h3>
  113 + </div>
  114 + <div class="panel-body">
  115 + <p>{% trans 'No pending tasks at the moment.' %}</p>
  116 + </div>
  117 + </div>
94 {% endblock rightbar %} 118 {% endblock rightbar %}
courses/templates/subject/delete.html
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 <div class="panel-body"> 8 <div class="panel-body">
9 <form action="" method="post"> 9 <form action="" method="post">
10 {% csrf_token %} 10 {% csrf_token %}
11 - <h2>{% trans 'Are you sure you want to delete the category' %} "{{subject}}"?</h2> 11 + <h2>{% trans 'Are you sure you want to delete the subject' %} "{{subject}}"?</h2>
12 <input type="submit" class="btn btn-raised btn-success btn-lg" value="{% trans 'Yes' %}" /> 12 <input type="submit" class="btn btn-raised btn-success btn-lg" value="{% trans 'Yes' %}" />
13 <a href="{% url 'course:view_subject' subject.slug%}" class="btn btn-raised btn-danger btn-lg">{% trans 'No' %}</a> 13 <a href="{% url 'course:view_subject' subject.slug%}" class="btn btn-raised btn-danger btn-lg">{% trans 'No' %}</a>
14 </form> 14 </form>
courses/templates/subject/form_view_student.html
1 {% load i18n %} 1 {% load i18n %}
2 2
3 <div class="panel panel-default"> 3 <div class="panel panel-default">
  4 + <a href="{% url 'course:view_topic' topic.slug %}">
4 <div class="panel-heading"> 5 <div class="panel-heading">
5 <div class="row"> 6 <div class="row">
6 <div class="col-md-9 col-sm-9"> 7 <div class="col-md-9 col-sm-9">
7 <h3>{{topic}}</h3> 8 <h3>{{topic}}</h3>
8 </div> 9 </div>
9 </div> 10 </div>
  11 + </div>
  12 + </a>
10 </div> 13 </div>
  14 +
11 <div class="panel-body"> 15 <div class="panel-body">
12 <p>{{topic.description|linebreaks}}</p> 16 <p>{{topic.description|linebreaks}}</p>
13 </div> 17 </div>
courses/templates/subject/form_view_teacher.html
1 {% load i18n %} 1 {% load i18n %}
2 2
3 <div class="panel panel-default"> 3 <div class="panel panel-default">
  4 + <a href="{% url 'course:view_topic' topic.slug %}">
4 <div class="panel-heading"> 5 <div class="panel-heading">
5 <div class="row"> 6 <div class="row">
6 <div class="col-md-9 col-sm-9"> 7 <div class="col-md-9 col-sm-9">
@@ -11,6 +12,7 @@ @@ -11,6 +12,7 @@
11 </div> 12 </div>
12 </div> 13 </div>
13 </div> 14 </div>
  15 + </a>
14 <div class="panel-body"> 16 <div class="panel-body">
15 <p>{{topic.description|linebreaks}}</p> 17 <p>{{topic.description|linebreaks}}</p>
16 </div> 18 </div>
courses/templates/subject/index.html
@@ -7,7 +7,12 @@ @@ -7,7 +7,12 @@
7 <ol class="breadcrumb"> 7 <ol class="breadcrumb">
8 <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> 8 <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>
9 <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li> 9 <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li>
10 - <li class="active">{% trans 'Manage Subjects' %}</li> 10 + {% if user|has_role:'professor' or user|has_role:'system_admin' %}
  11 + <li class="active">{% trans 'Manage Subjects' %}</li>
  12 + {% else %}
  13 + <li class="active">{{ subject.name }}</li>
  14 + {% endif %}
  15 +
11 </ol> 16 </ol>
12 {% endblock %} 17 {% endblock %}
13 18
@@ -67,8 +72,10 @@ @@ -67,8 +72,10 @@
67 {% include "subject/form_view_student.html" %} 72 {% include "subject/form_view_student.html" %}
68 {% endif %} 73 {% endif %}
69 {% endfor %} 74 {% endfor %}
  75 + {% if user|has_role:'system_admin' or topic.owner == user%}
  76 + <a name="create_topic" class="btn btn-primary btn-md btn-block" href="{% url 'course:create_topic' subject.slug %}">{% trans "Create Topic" %}</a>
  77 + {% endif %}
70 78
71 - <a name="create_topic" class="btn btn-primary btn-md btn-block" href="{% url 'course:create_topic' subject.slug %}">{% trans "Create Topic" %}</a>  
72 {% endblock %} 79 {% endblock %}
73 80
74 {% block rightbar %} 81 {% block rightbar %}
courses/templates/topic/index.html 0 → 100644
@@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
  1 +{% extends 'base.html' %}
  2 +
  3 +{% load static i18n permission_tags %}
  4 +
  5 +{% block breadcrumbs %}
  6 +
  7 + <ol class="breadcrumb">
  8 + <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>
  9 + <li><a href="{% url 'course:view_subject' subject.slug %}">{{ subject }}</a></li>
  10 + {% if user|has_role:'professor' or user|has_role:'system_admin' %}
  11 + <li class="active">{% trans 'Manage Topic' %}</li>
  12 + {% else %}
  13 + <li class="active">{{ topic.name }}</li>
  14 + {% endif %}
  15 +
  16 + </ol>
  17 +{% endblock %}
  18 +
  19 +{% block sidebar %}
  20 +
  21 + <div class="panel panel-primary">
  22 +
  23 + <div class="panel-heading">
  24 + <h3 class="panel-title">{{course}}</h3>
  25 + </div>
  26 +
  27 + <div class="panel-body">
  28 + <!--{% for subject in subjects %}
  29 + <div class="row">
  30 + <div class="col-md-12 col-sm-12">
  31 + {{subject}}
  32 + </div>
  33 + </div>
  34 + {% endfor %}-->
  35 + </div>
  36 + </div>
  37 +
  38 +
  39 +{% endblock %}
  40 +
  41 +{% block content %}
  42 + <div class="panel panel-info">
  43 + <div class="panel-heading">
  44 + <div class="row">
  45 + <div class="col-md-7 col-sm-7">
  46 + <h3>{{subject}}</h3>
  47 + </div>
  48 + <div class="col-md-2 col-sm-2">
  49 + {% if user|has_role:'system_admin' or user in subject.professors %}
  50 + <a href="{% url 'course:update_subject' subject.slug%}" class="btn">{% trans "edit" %}</a>
  51 + {% endif %}
  52 + </div>
  53 + <div class="col-md-3 col-sm-3">
  54 + {% if user|has_role:'system_admin' or user in subject.professors %}
  55 + <a href="{% url 'course:delete_subject' subject.slug%}" class="btn">{% trans "delete" %}</a>
  56 + {% endif %}
  57 + </div>
  58 + </div>
  59 + </div>
  60 + <div class="panel-body">
  61 + <p>
  62 + {{subject.description|linebreaks}}
  63 + </p>
  64 + </div>
  65 + </div>
  66 +<!--{% for topic in topics %}
  67 + {% if user|has_role:'system_admin' or topic.owner == user%}
  68 + {% include "subject/form_view_teacher.html" %}
  69 + {% else %}
  70 + {% include "subject/form_view_student.html" %}
  71 + {% endif %}
  72 +{% endfor %}
  73 + {% if user|has_role:'system_admin' or topic.owner == user%}
  74 + <a name="create_topic" class="btn btn-primary btn-md btn-block" href="{% url 'course:create_topic' subject.slug %}">{% trans "Create Topic" %}</a>
  75 + {% endif %}
  76 +
  77 +{% endblock %}-->
  78 +
  79 +{% block rightbar %}
  80 +
  81 + <div class="panel panel-warning">
  82 + <div class="panel-heading">
  83 + <h3 class="panel-title">{% trans "Pending Stuffs" %}</h3>
  84 + </div>
  85 + <div class="panel-body">
  86 +
  87 + </div>
  88 + </div>
  89 +{% endblock rightbar %}
courses/urls.py
@@ -4,10 +4,10 @@ from . import views @@ -4,10 +4,10 @@ from . import views
4 4
5 urlpatterns = [ 5 urlpatterns = [
6 url(r'^$', views.IndexView.as_view(), name='manage'), 6 url(r'^$', views.IndexView.as_view(), name='manage'),
7 - url(r'^create/$', views.CreateView.as_view(), name='create'),  
8 - url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateView.as_view(), name='update'), 7 + url(r'^create/$', views.CreateCourseView.as_view(), name='create'),
  8 + url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'),
9 url(r'^(?P<slug>[\w_-]+)/$', views.CourseView.as_view(), name='view'), 9 url(r'^(?P<slug>[\w_-]+)/$', views.CourseView.as_view(), name='view'),
10 - url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteView.as_view(), name='delete'), 10 + url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'),
11 url(r'^category/(?P<slug>[\w_-]+)/$', views.FilteredView.as_view(), name='filter'), 11 url(r'^category/(?P<slug>[\w_-]+)/$', views.FilteredView.as_view(), name='filter'),
12 url(r'^categories/$', views.IndexCatView.as_view(), name='manage_cat'), 12 url(r'^categories/$', views.IndexCatView.as_view(), name='manage_cat'),
13 url(r'^categories/create/$', views.CreateCatView.as_view(), name="create_cat"), 13 url(r'^categories/create/$', views.CreateCatView.as_view(), name="create_cat"),
@@ -15,9 +15,10 @@ urlpatterns = [ @@ -15,9 +15,10 @@ urlpatterns = [
15 url(r'^categories/(?P<slug>[\w_-]+)/$', views.ViewCat.as_view(), name='view_cat'), 15 url(r'^categories/(?P<slug>[\w_-]+)/$', views.ViewCat.as_view(), name='view_cat'),
16 url(r'^categories/delete/(?P<slug>[\w_-]+)/$', views.DeleteCatView.as_view(), name='delete_cat'), 16 url(r'^categories/delete/(?P<slug>[\w_-]+)/$', views.DeleteCatView.as_view(), name='delete_cat'),
17 url(r'^subjects/(?P<slug>[\w_-]+)/$', views.SubjectsView.as_view(), name='view_subject'), 17 url(r'^subjects/(?P<slug>[\w_-]+)/$', views.SubjectsView.as_view(), name='view_subject'),
18 - url(r'^topics/create/(?P<slug>[\w_-]+)/$', views.CreateTopicView.as_view(), name='create_topic'),  
19 - url(r'^topics/update/(?P<slug>[\w_-]+)/$', views.UpdateTopicView.as_view(), name='update_topic'),  
20 url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'), 18 url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'),
21 url(r'^subjects/update/(?P<slug>[\w_-]+)/$', views.UpdateSubjectView.as_view(), name='update_subject'), 19 url(r'^subjects/update/(?P<slug>[\w_-]+)/$', views.UpdateSubjectView.as_view(), name='update_subject'),
22 url(r'^subjects/delete/(?P<slug>[\w_-]+)/$', views.DeleteSubjectView.as_view(), name='delete_subject'), 20 url(r'^subjects/delete/(?P<slug>[\w_-]+)/$', views.DeleteSubjectView.as_view(), name='delete_subject'),
  21 + url(r'^topics/create/(?P<slug>[\w_-]+)/$', views.CreateTopicView.as_view(), name='create_topic'),
  22 + url(r'^topics/update/(?P<slug>[\w_-]+)/$', views.UpdateTopicView.as_view(), name='update_topic'),
  23 + url(r'^topics/(?P<slug>[\w_-]+)/$', views.TopicsView.as_view(), name='view_topic')
23 ] 24 ]
courses/views.py
@@ -12,10 +12,11 @@ from rolepermissions.verifications import has_role @@ -12,10 +12,11 @@ from rolepermissions.verifications import has_role
12 from django.db.models import Q 12 from django.db.models import Q
13 from rolepermissions.verifications import has_object_permission 13 from rolepermissions.verifications import has_object_permission
14 14
15 -from .forms import CourseForm, CategoryForm, SubjectForm,TopicForm 15 +from .forms import CourseForm, UpdateCourseForm, CategoryForm, SubjectForm,TopicForm
16 from .models import Course, Subject, Category,Topic 16 from .models import Course, Subject, Category,Topic
17 from core.mixins import NotificationMixin 17 from core.mixins import NotificationMixin
18 18
  19 +from datetime import date
19 20
20 class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): 21 class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView):
21 22
@@ -32,7 +33,7 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): @@ -32,7 +33,7 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView):
32 33
33 return context 34 return context
34 35
35 -class CreateView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edit.CreateView): 36 +class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edit.CreateView):
36 37
37 allowed_roles = ['professor', 'system_admin'] 38 allowed_roles = ['professor', 'system_admin']
38 login_url = reverse_lazy("core:home") 39 login_url = reverse_lazy("core:home")
@@ -47,8 +48,6 @@ class CreateView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edi @@ -47,8 +48,6 @@ class CreateView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edi
47 self.object.save() 48 self.object.save()
48 messages.success(self.request, _('Course created successfully!')) 49 messages.success(self.request, _('Course created successfully!'))
49 50
50 - return super(CreateView, self).form_valid(form)  
51 -  
52 def form_invalid(self, form): 51 def form_invalid(self, form):
53 print(form) 52 print(form)
54 return self.render_to_response(self.get_context_data(form=form)) 53 return self.render_to_response(self.get_context_data(form=form))
@@ -56,27 +55,80 @@ class CreateView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edi @@ -56,27 +55,80 @@ class CreateView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edi
56 def render_to_responssse(self, context, **response_kwargs): 55 def render_to_responssse(self, context, **response_kwargs):
57 return self.response_class(request=self.request, template=self.get_template_names(), context=context, using=self.template_engine) 56 return self.response_class(request=self.request, template=self.get_template_names(), context=context, using=self.template_engine)
58 57
59 -class UpdateView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): 58 + def get_context_data(self, **kwargs):
  59 + context = super(CreateCourseView, self).get_context_data(**kwargs)
  60 +
  61 + if has_role(self.request.user,'system_admin'):
  62 + courses = Course.objects.all()
  63 + elif has_role(self.request.user,'professor'):
  64 + courses = self.request.user.courses.all()
  65 + context['courses'] = courses
  66 + context['title'] = _("Create Course")
  67 + context['now'] = date.today()
  68 + return context
  69 +
  70 +class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
60 71
61 allowed_roles = ['professor', 'system_admin'] 72 allowed_roles = ['professor', 'system_admin']
62 login_url = reverse_lazy("core:home") 73 login_url = reverse_lazy("core:home")
63 redirect_field_name = 'next' 74 redirect_field_name = 'next'
64 template_name = 'course/update.html' 75 template_name = 'course/update.html'
65 model = Course 76 model = Course
66 - form_class = CourseForm 77 + form_class = UpdateCourseForm
  78 +
  79 + def dispatch(self, *args, **kwargs):
  80 + course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
  81 + if(not has_object_permission('update_course', self.request.user, course)):
  82 + return self.handle_no_permission()
  83 + return super(UpdateCourseView, self).dispatch(*args, **kwargs)
  84 +
  85 + def get_context_data(self, **kwargs):
  86 + context = super(UpdateCourseView, self).get_context_data(**kwargs)
  87 + course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
  88 +
  89 + if has_role(self.request.user,'system_admin'):
  90 + courses = Course.objects.all()
  91 + elif has_role(self.request.user,'professor'):
  92 + courses = self.request.user.courses.all()
  93 + context['courses'] = courses
  94 + context['title'] = course.name
  95 + context['now'] = date.today()
  96 + return context
  97 +
  98 + def get_success_url(self):
  99 + return reverse_lazy('course:view', kwargs={'slug' : self.object.slug})
  100 +
  101 +
  102 +
  103 +class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
  104 +
  105 + allowed_roles = ['professor', 'system_admin']
  106 + login_url = reverse_lazy("core:home")
  107 + redirect_field_name = 'next'
  108 + model = Course
  109 + template_name = 'course/delete.html'
67 success_url = reverse_lazy('course:manage') 110 success_url = reverse_lazy('course:manage')
68 111
69 - def form_valid(self, form):  
70 - self.object = form.save(commit = False)  
71 - self.object.slug = slugify(self.object.name)  
72 - self.object.save() 112 + def dispatch(self, *args, **kwargs):
  113 + course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
  114 + if(not has_object_permission('delete_course', self.request.user, course)):
  115 + return self.handle_no_permission()
  116 + return super(DeleteCourseView, self).dispatch(*args, **kwargs)
73 117
74 - return super(UpdateView, self).form_valid(form) 118 + def get_context_data(self, **kwargs):
  119 + context = super(DeleteCourseView, self).get_context_data(**kwargs)
  120 + course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
75 121
76 - def render_to_response(self, context, **response_kwargs):  
77 - messages.success(self.request, _('Course edited successfully!')) 122 + if has_role(self.request.user,'system_admin'):
  123 + courses = Course.objects.all()
  124 + elif has_role(self.request.user,'professor'):
  125 + courses = self.request.user.courses.all()
  126 + context['courses'] = courses
  127 + print (courses,"jdhksjbjs")
  128 + context['title'] = course.name
  129 +
  130 + return context
78 131
79 - return self.response_class(request=self.request, template=self.get_template_names(), context=context, using=self.template_engine)  
80 132
81 class CourseView(LoginRequiredMixin, NotificationMixin, generic.DetailView): 133 class CourseView(LoginRequiredMixin, NotificationMixin, generic.DetailView):
82 134
@@ -90,7 +142,7 @@ class CourseView(LoginRequiredMixin, NotificationMixin, generic.DetailView): @@ -90,7 +142,7 @@ class CourseView(LoginRequiredMixin, NotificationMixin, generic.DetailView):
90 context = super(CourseView, self).get_context_data(**kwargs) 142 context = super(CourseView, self).get_context_data(**kwargs)
91 course = get_object_or_404(Course, slug = self.kwargs.get('slug')) 143 course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
92 if has_role(self.request.user,'system_admin'): 144 if has_role(self.request.user,'system_admin'):
93 - subjects = Subject.objects.all() 145 + subjects = course.subjects.all()
94 elif has_role(self.request.user,'professor'): 146 elif has_role(self.request.user,'professor'):
95 subjects = course.subjects.filter(professors__in=[self.request.user]) 147 subjects = course.subjects.filter(professors__in=[self.request.user])
96 elif has_role(self.request.user, 'student'): 148 elif has_role(self.request.user, 'student'):
@@ -239,6 +291,29 @@ class SubjectsView(LoginRequiredMixin, generic.ListView): @@ -239,6 +291,29 @@ class SubjectsView(LoginRequiredMixin, generic.ListView):
239 context['topics'] = subject.topics.all() 291 context['topics'] = subject.topics.all()
240 return context 292 return context
241 293
  294 +class TopicsView(LoginRequiredMixin, generic.ListView):
  295 +
  296 + login_url = reverse_lazy("core:home")
  297 + redirect_field_name = 'next'
  298 + template_name = 'topic/index.html'
  299 + context_object_name = 'topics'
  300 + model = Topic
  301 +
  302 + def get_queryset(self):
  303 + topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
  304 + subject = topic.subject
  305 + context = subject.topics.filter(visible=True)
  306 + #if (self.request.user in subject.professors.all() or has_role(self.request.user,'system_admin')):
  307 + #context = subject.topics.all() <- Change it By Activities
  308 + return context
  309 +
  310 + def get_context_data(self, **kwargs):
  311 + topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
  312 + context = super(TopicsView, self).get_context_data(**kwargs)
  313 + context['topic'] = topic
  314 + context['subject'] = topic.subject
  315 + return context
  316 +
242 class CreateTopicView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, generic.edit.CreateView): 317 class CreateTopicView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, generic.edit.CreateView):
243 318
244 allowed_roles = ['professor', 'system_admin'] 319 allowed_roles = ['professor', 'system_admin']
@@ -386,4 +461,4 @@ class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): @@ -386,4 +461,4 @@ class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
386 return context 461 return context
387 462
388 def get_success_url(self): 463 def get_success_url(self):
389 - return reverse_lazy('course:view_subject', kwargs={'slug' : self.object.course.subjects.all()[0].slug}) 464 + return reverse_lazy('course:view', kwargs={'slug' : self.object.course.slug})
users/admin.py
1 from django.contrib import admin 1 from django.contrib import admin
2 from .models import User 2 from .models import User
3 -from .forms import ProfileForm 3 +from .forms import UserForm
4 4
5 class UserAdmin(admin.ModelAdmin): 5 class UserAdmin(admin.ModelAdmin):
6 list_display = ['username', 'name', 'email', 'is_staff', 'is_active'] 6 list_display = ['username', 'name', 'email', 'is_staff', 'is_active']
7 search_fields = ['username', 'name', 'email'] 7 search_fields = ['username', 'name', 'email']
8 - form = ProfileForm 8 + form = UserForm
9 9
10 admin.site.register(User, UserAdmin) 10 admin.site.register(User, UserAdmin)
11 \ No newline at end of file 11 \ No newline at end of file
users/forms.py
1 # coding=utf-8 1 # coding=utf-8
2 - 2 +import os
  3 +from django.conf import settings
3 from django import forms 4 from django import forms
4 from django.utils.translation import ugettext_lazy as _ 5 from django.utils.translation import ugettext_lazy as _
  6 +from rolepermissions.shortcuts import assign_role
5 from .models import User 7 from .models import User
6 8
7 9
@@ -25,10 +27,32 @@ class ProfileForm(forms.ModelForm): @@ -25,10 +27,32 @@ class ProfileForm(forms.ModelForm):
25 } 27 }
26 28
27 class UserForm(forms.ModelForm): 29 class UserForm(forms.ModelForm):
  30 + def save(self, commit=True):
  31 + super(UserForm, self).save(commit=False)
  32 +
  33 + #if not self.instance.image:
  34 + # self.instance.image = os.path.join(os.path.dirname(settings.BASE_DIR), 'uploads', 'no_image.jpg')
  35 +
  36 + self.instance.set_password(self.cleaned_data['password'])
  37 + self.instance.save()
  38 +
  39 + if self.instance.is_staff:
  40 + assign_role(self.instance, 'system_admin')
  41 + elif self.instance.type_profile == 2:
  42 + assign_role(self.instance, 'student')
  43 + elif self.instance.type_profile == 1:
  44 + assign_role(self.instance, 'professor')
  45 +
  46 + self.instance.save()
  47 +
  48 + return self.instance
28 49
29 class Meta: 50 class Meta:
30 model = User 51 model = User
31 - fields = ['username', 'name', 'email', 'birth_date', 'city', 'state', 'gender', 'type_profile', 'cpf', 'phone', 'image', 'is_staff', 'is_active'] 52 + fields = ['username', 'name', 'email', 'password', 'birth_date', 'city', 'state', 'gender', 'type_profile', 'cpf', 'phone', 'image', 'is_staff', 'is_active']
  53 + widgets = {
  54 + 'password':forms.PasswordInput
  55 + }
32 56
33 class EditUserForm(forms.ModelForm): 57 class EditUserForm(forms.ModelForm):
34 58
users/migrations/0013_auto_20160915_2334.py 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-09-16 02:34
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('users', '0012_auto_20160908_1625'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.AlterField(
  16 + model_name='user',
  17 + name='image',
  18 + field=models.ImageField(blank=True, upload_to='users/', verbose_name='Image'),
  19 + ),
  20 + ]
users/models.py
@@ -4,6 +4,7 @@ from django.db import models @@ -4,6 +4,7 @@ from django.db import models
4 from django.core import validators 4 from django.core import validators
5 from django.utils.translation import ugettext_lazy as _ 5 from django.utils.translation import ugettext_lazy as _
6 from django.contrib.auth.models import AbstractBaseUser, UserManager, PermissionsMixin 6 from django.contrib.auth.models import AbstractBaseUser, UserManager, PermissionsMixin
  7 +from django.contrib.staticfiles.templatetags.staticfiles import static
7 8
8 class User(AbstractBaseUser, PermissionsMixin): 9 class User(AbstractBaseUser, PermissionsMixin):
9 10
@@ -19,7 +20,7 @@ class User(AbstractBaseUser, PermissionsMixin): @@ -19,7 +20,7 @@ class User(AbstractBaseUser, PermissionsMixin):
19 city = models.CharField(_('City'), max_length = 90, blank = True) 20 city = models.CharField(_('City'), max_length = 90, blank = True)
20 state = models.CharField(_('State'), max_length = 30, blank = True) 21 state = models.CharField(_('State'), max_length = 30, blank = True)
21 gender = models.CharField(_('Gender'), max_length = 1, choices = (('M', _('Male')), ('F', _('Female')))) 22 gender = models.CharField(_('Gender'), max_length = 1, choices = (('M', _('Male')), ('F', _('Female'))))
22 - image = models.ImageField(verbose_name = _('Image'), blank = True, upload_to = 'users/', default = 'no_image.jpg') 23 + image = models.ImageField(verbose_name = _('Image'), blank = True, upload_to = 'users/')
23 birth_date = models.DateField(_('Birth Date'), null = True, blank = True) 24 birth_date = models.DateField(_('Birth Date'), null = True, blank = True)
24 phone = models.CharField(_('Phone'), max_length = 30, blank = True) 25 phone = models.CharField(_('Phone'), max_length = 30, blank = True)
25 cpf = models.CharField(_('Cpf'), max_length = 15, blank = True) 26 cpf = models.CharField(_('Cpf'), max_length = 15, blank = True)
@@ -40,8 +41,15 @@ class User(AbstractBaseUser, PermissionsMixin): @@ -40,8 +41,15 @@ class User(AbstractBaseUser, PermissionsMixin):
40 def __str__(self): 41 def __str__(self):
41 return self.name or self.username 42 return self.name or self.username
42 43
43 - def det_full_name(self): 44 + def get_full_name(self):
44 return str(self) 45 return str(self)
45 46
46 def get_short_name(self): 47 def get_short_name(self):
47 - return str(self).split(" ")[0]  
48 \ No newline at end of file 48 \ No newline at end of file
  49 + return str(self).split(" ")[0]
  50 +
  51 + @property
  52 + def image_url(self):
  53 + if self.image and hasattr(self.image, 'url'):
  54 + return self.image.url
  55 + else:
  56 + return static('img/no_image.jpg')
49 \ No newline at end of file 57 \ No newline at end of file
users/templates/list_users.html
1 -{% extends 'base.html' %} 1 +{% extends 'home.html' %}
2 2
3 -{% load i18n pagination %} 3 +{% load i18n pagination django_bootstrap_breadcrumbs %}
4 4
5 {% block breadcrumbs %} 5 {% block breadcrumbs %}
6 - <div class="row">  
7 - <div class="col-md-12">  
8 - <ul class="breadcrumb" style="margin-bottom: 5px;">  
9 - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>  
10 - <li class="active">{% trans 'Manage Users' %}</li>  
11 - </ul>  
12 - </div>  
13 - </div> 6 +
  7 + {{ block.super }}
  8 + {% breadcrumb 'Manage Users' 'users:manage' %}
  9 +
14 {% endblock %} 10 {% endblock %}
15 11
16 {% block sidebar %} 12 {% block sidebar %}
@@ -52,7 +48,7 @@ @@ -52,7 +48,7 @@
52 <p>{% trans 'Email' %}: {{ acc.email }}</p> 48 <p>{% trans 'Email' %}: {{ acc.email }}</p>
53 <p>{% trans 'Contact' %}: {{ acc.phone }}</p> 49 <p>{% trans 'Contact' %}: {{ acc.phone }}</p>
54 <div align="right"> 50 <div align="right">
55 - <a href="javascript:void(0)" class="btn btn-raised btn-success">{% trans 'Edit' %}</a> 51 + <a href="{% url 'users:update' acc.username %}" class="btn btn-raised btn-success">{% trans 'Edit' %}</a>
56 <a href="javascript:void(0)" class="btn btn-raised btn-primary">{% trans 'Delete' %}</a> 52 <a href="javascript:void(0)" class="btn btn-raised btn-primary">{% trans 'Delete' %}</a>
57 </div> 53 </div>
58 </div> 54 </div>
@@ -68,3 +64,6 @@ @@ -68,3 +64,6 @@
68 </div> 64 </div>
69 {% endif %} 65 {% endif %}
70 {% endblock %} 66 {% endblock %}
  67 +
  68 +{% block rightbar %}
  69 +{% endblock rightbar %}
users/templates/users/create.html
1 -{% extends 'app/base.html' %} 1 +{% extends 'list_users.html' %}
2 2
3 {% load static i18n %} 3 {% load static i18n %}
4 {% load widget_tweaks %} 4 {% load widget_tweaks %}
5 5
  6 +{% load django_bootstrap_breadcrumbs %}
  7 +
6 {% block breadcrumbs %} 8 {% block breadcrumbs %}
7 - <ol class="breadcrumb">  
8 - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>  
9 - <li class="active">{% trans 'New User' %}</li>  
10 - </ol>  
11 -{% endblock %}  
12 9
13 -{% block sidebar %}  
14 - <div class="list-group">  
15 - <a href="{% url 'users:manage' %}" class="list-group-item">  
16 - {% trans 'System Users' %}  
17 - </a>  
18 - <a href="{% url 'users:create' %}" class="list-group-item active">  
19 - {% trans 'New Account' %}  
20 - </a>  
21 - <a href="#" class="list-group-item">  
22 - {% trans 'Send Mail' %}  
23 - </a>  
24 - </div> 10 + {{ block.super }}
  11 + {% breadcrumb 'Add User' 'users:create' %}
  12 +
25 {% endblock %} 13 {% endblock %}
26 14
  15 +
27 {% block content %} 16 {% block content %}
28 - <div class="alert alert-info alert-dismissible" role="alert">  
29 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
30 - <span aria-hidden="true">&times;</span>  
31 - </button>  
32 - <p>{% trans 'All fields are required' %}</p>  
33 - </div> 17 + {% if messages %}
  18 + {% for message in messages %}
  19 + <div class="alert alert-success alert-dismissible" role="alert">
  20 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  21 + <span aria-hidden="true">&times;</span>
  22 + </button>
  23 + <p>{{ message }}</p>
  24 + </div>
  25 + {% endfor %}
  26 + {% endif %}
34 27
35 - <form method="post" action="" enctype="multipart/form-data">  
36 - {% csrf_token %}  
37 - {% for field in form %}  
38 - <div class="form-group{% if form.has_error %} has-error {% endif %}">  
39 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
40 - {% render_field field class='form-control input-sm' %}  
41 - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>  
42 - {% if field.errors.length > 0 %}  
43 - <div class="alert alert-danger alert-dismissible" role="alert">  
44 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
45 - <span aria-hidden="true">&times;</span>  
46 - </button>  
47 - <ul>  
48 - {% for error in field.errors %}  
49 - <li>{{ error }}</li>  
50 - {% endfor %}  
51 - </ul> 28 + <div class="card">
  29 + <div class="card-content">
  30 + <div class="card-body">
  31 + <form method="post" action="" enctype="multipart/form-data">
  32 + {% csrf_token %}
  33 + {% for field in form %}
  34 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  35 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  36 + {% if field.auto_id == 'id_birth_date' %}
  37 + {% render_field field class='form-control input-sm' type='date' %}
  38 + <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
  39 + {% elif field.auto_id == 'id_image' %}
  40 + {% render_field field class='form-control input-sm' %}
  41 + <div class="input-group">
  42 + <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your photo...' %}">
  43 + <span class="input-group-btn input-group-sm">
  44 + <button type="button" class="btn btn-fab btn-fab-mini">
  45 + <i class="material-icons">attach_file</i>
  46 + </button>
  47 + </span>
  48 + </div>
  49 + {% elif field.auto_id == 'id_is_staff' or field.auto_id == 'id_is_active' %}
  50 + <div class="checkbox">
  51 + <label>
  52 + {% render_field field type='checkbox' %}
  53 + </label>
  54 + </div>
  55 + {% else %}
  56 + {% render_field field class='form-control input-sm' %}
  57 + <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
  58 + {% endif %}
  59 + {% if field.errors.length > 0 %}
  60 + <div class="alert alert-danger alert-dismissible" role="alert">
  61 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  62 + <span aria-hidden="true">&times;</span>
  63 + </button>
  64 + <ul>
  65 + {% for error in field.errors %}
  66 + <li>{{ error }}</li>
  67 + {% endfor %}
  68 + </ul>
  69 + </div>
  70 + </div>
  71 + {% endif %}
  72 + </div>
  73 + {% endfor %}
  74 + <div class="col-md-offset-2 col-md-2 col-sm-2 col-xs-2">
  75 + <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />
  76 + </div>
  77 + <div class="col-md-offset-3 col-md-2 col-sm-2 col-xs-2">
  78 + <a href="{% url 'users:manage' %}" class="btn btn-sm btn-success" >{% trans 'Cancel' %}</a>
52 </div> 79 </div>
53 - </div>  
54 - {% endif %} 80 + </form>
55 </div> 81 </div>
56 - {% endfor %}  
57 - <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />  
58 - </form> 82 + </div>
  83 + </div>
  84 +
59 <br clear="all" /> 85 <br clear="all" />
60 {% endblock %} 86 {% endblock %}
users/templates/users/update.html
1 -{% extends 'app/base.html' %} 1 +{% extends 'list_users.html' %}
2 2
3 {% load static i18n %} 3 {% load static i18n %}
4 {% load widget_tweaks %} 4 {% load widget_tweaks %}
5 5
  6 +{% load django_bootstrap_breadcrumbs %}
  7 +
6 {% block breadcrumbs %} 8 {% block breadcrumbs %}
7 - <ol class="breadcrumb">  
8 - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>  
9 - <li class="active">{% trans 'Edit user' %}</li>  
10 - </ol>  
11 -{% endblock %}  
12 9
13 -{% block sidebar %}  
14 - <div class="list-group">  
15 - <a href="{% url 'users:manage' %}" class="list-group-item">  
16 - {% trans 'System Users' %}  
17 - </a>  
18 - <a href="{% url 'users:create' %}" class="list-group-item">  
19 - {% trans 'New Account' %}  
20 - </a>  
21 - <a href="#" class="list-group-item">  
22 - {% trans 'Send Mail' %}  
23 - </a>  
24 - </div> 10 + {{ block.super }}
  11 + {% breadcrumb 'Update User' 'users:update' %}
  12 +
25 {% endblock %} 13 {% endblock %}
26 14
  15 +
27 {% block content %} 16 {% block content %}
28 - <div class="alert alert-info alert-dismissible" role="alert">  
29 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
30 - <span aria-hidden="true">&times;</span>  
31 - </button>  
32 - <p>{% trans 'All fields are required' %}</p>  
33 - </div> 17 + {% if messages %}
  18 + {% for message in messages %}
  19 + <div class="alert alert-success alert-dismissible" role="alert">
  20 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  21 + <span aria-hidden="true">&times;</span>
  22 + </button>
  23 + <p>{{ message }}</p>
  24 + </div>
  25 + {% endfor %}
  26 + {% endif %}
34 27
35 - <form method="post" action="" enctype="multipart/form-data">  
36 - {% csrf_token %}  
37 - {% for field in form %}  
38 - <div class="form-group{% if form.has_error %} has-error {% endif %}">  
39 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
40 - {% render_field field class='form-control input-sm' %}  
41 - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>  
42 - {% if field.errors.length > 0 %}  
43 - <div class="alert alert-danger alert-dismissible" role="alert">  
44 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
45 - <span aria-hidden="true">&times;</span>  
46 - </button>  
47 - <ul>  
48 - {% for error in field.errors %}  
49 - <li>{{ error }}</li>  
50 - {% endfor %}  
51 - </ul> 28 + <div class="card">
  29 + <div class="card-content">
  30 + <div class="card-body">
  31 + <form method="post" action="" enctype="multipart/form-data">
  32 + {% csrf_token %}
  33 + {% for field in form %}
  34 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  35 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  36 + {% if field.auto_id == 'id_birth_date' %}
  37 + {% render_field field class='form-control input-sm' type='date' %}
  38 + <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
  39 + {% elif field.auto_id == 'id_image' %}
  40 + {% render_field field class='form-control input-sm' %}
  41 + <div class="input-group">
  42 + <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your photo...' %}">
  43 + <span class="input-group-btn input-group-sm">
  44 + <button type="button" class="btn btn-fab btn-fab-mini">
  45 + <i class="material-icons">attach_file</i>
  46 + </button>
  47 + </span>
  48 + </div>
  49 + {% elif field.auto_id == 'id_is_staff' or field.auto_id == 'id_is_active' %}
  50 + <div class="checkbox">
  51 + <label>
  52 + {% render_field field type='checkbox' %}
  53 + </label>
  54 + </div>
  55 + {% else %}
  56 + {% render_field field class='form-control input-sm' %}
  57 + <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
  58 + {% endif %}
  59 + {% if field.errors.length > 0 %}
  60 + <div class="alert alert-danger alert-dismissible" role="alert">
  61 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  62 + <span aria-hidden="true">&times;</span>
  63 + </button>
  64 + <ul>
  65 + {% for error in field.errors %}
  66 + <li>{{ error }}</li>
  67 + {% endfor %}
  68 + </ul>
  69 + </div>
  70 + </div>
  71 + {% endif %}
  72 + </div>
  73 + {% endfor %}
  74 + <div class="col-md-offset-2 col-md-2 col-sm-2 col-xs-2">
  75 + <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />
  76 + </div>
  77 + <div class="col-md-offset-3 col-md-2 col-sm-2 col-xs-2">
  78 + <a href="{% url 'users:manage' %}" class="btn btn-sm btn-success" >{% trans 'Cancel' %}</a>
52 </div> 79 </div>
53 - </div>  
54 - {% endif %} 80 + </form>
55 </div> 81 </div>
56 - {% endfor %}  
57 - <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />  
58 - </form> 82 + </div>
  83 + </div>
59 <br clear="all" /> 84 <br clear="all" />
60 {% endblock %} 85 {% endblock %}