login bereich

This commit is contained in:
2018-03-22 20:13:07 +01:00
parent a74f6d0ee4
commit 5e1b34bfef
65 changed files with 1540 additions and 1057 deletions

View File

@@ -1,19 +1,11 @@
import xlwt
import json
from aldryn_forms.utils import get_user_model
from django.conf.urls import url
from django.contrib.admin.utils import unquote
from django.http import HttpResponse
from django.utils.text import slugify
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from memberzone.models import MemberTask, MemberTaskFormField, MemberTaskRegistration, MemberDownloadFile, \
MemberDownloadTag, Profile, MemberDownloadSection
from parler.admin import TranslatableAdmin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from memberzone.models import Profile, MemberTask, MemberDownloadSection, MemberDownloadTag, MemberDownloadFile
User = get_user_model()
@@ -34,86 +26,33 @@ admin.site.unregister(User)
admin.site.register(User, UserAdmin)
class MemberTaskFormFieldInlineAdmin(admin.TabularInline):
model = MemberTaskFormField
extra = 0
prepopulated_fields = {
'name': ('label',)
}
@admin.register(MemberTask)
class MemberTaskAdmin(admin.ModelAdmin):
list_display = ('title', 'publish_date', 'deadline')
class MemberTaskAdmin(TranslatableAdmin):
list_display = ('title', 'published', 'publish_date')
list_filter = ('groups',)
filter_horizontal = ('groups',)
prepopulated_fields = {
'slug': ('title',)
}
inlines = [MemberTaskFormFieldInlineAdmin, ]
def get_urls(self):
info = self.model._meta.app_label, self.model._meta.model_name
return [
url(
r'^(.+)/export/$',
self.admin_site.admin_view(self.participants_export_view),
name='%s_%s_participants_export' % info,
),
] + super(MemberTaskAdmin, self).get_urls()
def participants_export_view(self, request, object_id, *args, **kwargs):
obj = self.get_object(request, unquote(object_id))
wb = xlwt.Workbook()
ws = wb.add_sheet('Teilnehmerliste')
r = 0
c = 0
fields = []
for field in obj.fields.all():
ws.write(r, c, field.label)
fields.append(field.name.replace('-', '_'))
c += 1
for participant in obj.registrations.all():
for data_set in json.loads(participant.form_data):
r += 1
c = 0
for field in fields:
value = data_set.get(field, '')
if isinstance(value, list):
value = ', '.join(value)
ws.write(r, c, value)
c += 1
response = HttpResponse(content_type="application/ms-excel")
response['Content-Disposition'] = 'attachment; filename=%s-teilnehmer.xls' % slugify(obj.title)
wb.save(response)
return response
@admin.register(MemberTaskRegistration)
class MemberTaskRegistrationAdmin(admin.ModelAdmin):
readonly_fields = ['task', 'user', 'form_data', 'cdate']
def has_delete_permission(self, request, obj=None):
return False
def has_add_permission(self, request):
return False
readonly_fields = ('informed_users',)
fieldsets = (
(None, {'fields': ('title', 'published', 'image', 'cropping')}),
(_('Permissions'), {'fields': ('groups',)}),
(_('Veröffentlichung'), {'fields': ('publish_date',)}),
(_('Information'), {'fields': ('informed_users',)}),
)
@admin.register(MemberDownloadSection)
class MemberDownloadSectionAdmin(admin.ModelAdmin):
class MemberDownloadSectionAdmin(TranslatableAdmin):
list_display = ('title', 'ordering')
list_editable = ['ordering']
@admin.register(MemberDownloadTag)
class MemberDownloadTagAdmin(admin.ModelAdmin):
class MemberDownloadTagAdmin(TranslatableAdmin):
pass
@admin.register(MemberDownloadFile)
class MemberDownloadFileAdmin(admin.ModelAdmin):
class MemberDownloadFileAdmin(TranslatableAdmin):
list_display = ('label', 'ordering')
list_editable = ['ordering']
list_filter = ('section', 'groups')

View File

@@ -1,8 +1,21 @@
from django import forms
from django.contrib.auth.forms import AuthenticationForm
from memberzone.models import Profile
class LoginForm(AuthenticationForm):
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(*args, **kwargs)
for _, value in self.fields.items():
value.widget.attrs['placeholder'] = value.label
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['first_name', 'last_name', 'street', 'zip', 'place', 'email']
def __init__(self, *args, **kwargs):
super(ProfileEditForm, self).__init__(*args, **kwargs)
self.fields['zip'].widget = forms.TextInput()

View File

@@ -0,0 +1,240 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-03-22 10:52
from __future__ import unicode_literals
import cms.models.fields
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import image_cropping.fields
import project.utils
class Migration(migrations.Migration):
dependencies = [
('cms', '0018_pagenode'),
('memberzone', '0002_auto_20180321_1256'),
]
operations = [
migrations.CreateModel(
name='MemberDownloadFileTranslation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('language_code', models.CharField(db_index=True, max_length=15, verbose_name='Language')),
('name', models.CharField(blank=True, max_length=512, null=True, verbose_name='Name')),
('description', models.TextField(blank=True, null=True, verbose_name='Beschreibung')),
('file', models.FileField(max_length=512, upload_to='protected_files')),
],
options={
'db_table': 'memberzone_memberdownloadfile_translation',
'default_permissions': (),
'managed': True,
'db_tablespace': '',
'verbose_name': 'Mitglieder Download Translation',
},
),
migrations.CreateModel(
name='MemberDownloadSectionTranslation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('language_code', models.CharField(db_index=True, max_length=15, verbose_name='Language')),
('title', models.CharField(max_length=100, verbose_name='Title')),
],
options={
'db_table': 'memberzone_memberdownloadsection_translation',
'default_permissions': (),
'managed': True,
'db_tablespace': '',
'verbose_name': 'Mitglieder Download Section Translation',
},
),
migrations.CreateModel(
name='MemberDownloadTagTranslation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('language_code', models.CharField(db_index=True, max_length=15, verbose_name='Language')),
('name', models.CharField(max_length=100, verbose_name='Name')),
],
options={
'db_table': 'memberzone_memberdownloadtag_translation',
'default_permissions': (),
'managed': True,
'db_tablespace': '',
'verbose_name': 'Mitglieder Download Tag Translation',
},
),
migrations.CreateModel(
name='MemberTaskTranslation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('language_code', models.CharField(db_index=True, max_length=15, verbose_name='Language')),
('title', models.CharField(max_length=100, verbose_name='Title')),
],
options={
'db_table': 'memberzone_membertask_translation',
'default_permissions': (),
'managed': True,
'db_tablespace': '',
'verbose_name': 'Mitglieder Aufgabe Translation',
},
),
migrations.AlterUniqueTogether(
name='membertaskformfield',
unique_together=set([]),
),
migrations.RemoveField(
model_name='membertaskformfield',
name='task',
),
migrations.AlterUniqueTogether(
name='membertaskregistration',
unique_together=set([]),
),
migrations.RemoveField(
model_name='membertaskregistration',
name='task',
),
migrations.RemoveField(
model_name='membertaskregistration',
name='user',
),
migrations.AlterModelOptions(
name='memberdownloadfile',
options={'ordering': ['ordering'], 'verbose_name': 'Mitglieder Download', 'verbose_name_plural': 'Mitglieder Downloads'},
),
migrations.RemoveField(
model_name='memberdownloadfile',
name='description',
),
migrations.RemoveField(
model_name='memberdownloadfile',
name='file',
),
migrations.RemoveField(
model_name='memberdownloadfile',
name='name',
),
migrations.RemoveField(
model_name='memberdownloadsection',
name='title',
),
migrations.RemoveField(
model_name='memberdownloadtag',
name='name',
),
migrations.RemoveField(
model_name='membertask',
name='bodytext',
),
migrations.RemoveField(
model_name='membertask',
name='deadline',
),
migrations.RemoveField(
model_name='membertask',
name='folder',
),
migrations.RemoveField(
model_name='membertask',
name='form_bodytext',
),
migrations.RemoveField(
model_name='membertask',
name='max_num',
),
migrations.RemoveField(
model_name='membertask',
name='slug',
),
migrations.RemoveField(
model_name='membertask',
name='sub_title',
),
migrations.RemoveField(
model_name='membertask',
name='submit_text',
),
migrations.RemoveField(
model_name='membertask',
name='success_bodytext',
),
migrations.RemoveField(
model_name='membertask',
name='success_title',
),
migrations.RemoveField(
model_name='membertask',
name='title',
),
migrations.AddField(
model_name='membertask',
name='cropping',
field=image_cropping.fields.ImageRatioField('image', '1200x800', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping'),
),
migrations.AddField(
model_name='membertask',
name='placeholder',
field=cms.models.fields.PlaceholderField(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, slotname='task_placeholder', to='cms.Placeholder'),
),
migrations.AlterField(
model_name='membertask',
name='image',
field=project.utils.CroppableFilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild'),
),
migrations.AlterField(
model_name='profile',
name='first_name',
field=models.CharField(default='', max_length=255, verbose_name='Vorname'),
preserve_default=False,
),
migrations.AlterField(
model_name='profile',
name='last_name',
field=models.CharField(default='', max_length=255, verbose_name='Nachname'),
preserve_default=False,
),
migrations.DeleteModel(
name='MemberTaskFormField',
),
migrations.DeleteModel(
name='MemberTaskRegistration',
),
migrations.AddField(
model_name='membertasktranslation',
name='master',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='memberzone.MemberTask'),
),
migrations.AddField(
model_name='memberdownloadtagtranslation',
name='master',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='memberzone.MemberDownloadTag'),
),
migrations.AddField(
model_name='memberdownloadsectiontranslation',
name='master',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='memberzone.MemberDownloadSection'),
),
migrations.AddField(
model_name='memberdownloadfiletranslation',
name='master',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='memberzone.MemberDownloadFile'),
),
migrations.AlterUniqueTogether(
name='membertasktranslation',
unique_together=set([('language_code', 'master')]),
),
migrations.AlterUniqueTogether(
name='memberdownloadtagtranslation',
unique_together=set([('language_code', 'master')]),
),
migrations.AlterUniqueTogether(
name='memberdownloadsectiontranslation',
unique_together=set([('language_code', 'master')]),
),
migrations.AlterUniqueTogether(
name='memberdownloadfiletranslation',
unique_together=set([('language_code', 'master')]),
),
]

View File

@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-03-22 11:21
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('memberzone', '0003_auto_20180322_1052'),
]
operations = [
migrations.AddField(
model_name='membertask',
name='published',
field=models.BooleanField(default=False, verbose_name='Veröffentlichen'),
),
]

View File

@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-03-22 12:05
from __future__ import unicode_literals
import cms.models.fields
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('memberzone', '0004_membertask_published'),
]
operations = [
migrations.AddField(
model_name='membertask',
name='informed_users',
field=models.ManyToManyField(blank=True, null=True, to=settings.AUTH_USER_MODEL, verbose_name='Als gelesen markiert von:'),
),
migrations.AlterField(
model_name='membertask',
name='placeholder',
field=cms.models.fields.PlaceholderField(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, slotname='content', to='cms.Placeholder'),
),
]

View File

@@ -1,18 +1,18 @@
from cms.models.fields import PlaceholderField
import os
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.core.files.storage import default_storage
from djangocms_text_ckeditor.fields import HTMLField
from django import forms
from django.conf import settings
from django.db import models
from django.urls import reverse_lazy
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from filer.fields.folder import FilerFolderField
from filer.fields.image import FilerImageField
from filer.models import Image as ImageModel
from image_cropping import ImageRatioField
from parler.models import TranslatableModel, TranslatedFields
from memberzone.storage import PrivateS3MediaStorage
from project.utils import CroppableFilerImageField
class Profile(models.Model):
@@ -25,149 +25,69 @@ class Profile(models.Model):
email = models.EmailField(verbose_name=_('E-Mail'), null=True, blank=True)
class Meta:
verbose_name = _('User Profil')
verbose_name_plural = _('User Profile')
verbose_name = 'User Profil'
verbose_name_plural = 'User Profile'
def __str__(self):
return self.full_name
@property
def full_name(self):
return '{} {}'.format(self.first_name, self.last_name)
class MemberTask(models.Model):
groups = models.ManyToManyField(Group, verbose_name=_('Mitglieder Gruppe'), related_name='tasks')
title = models.CharField(max_length=100, verbose_name=_('Title'))
slug = models.SlugField(verbose_name=_('slug'), unique=True)
sub_title = models.CharField(max_length=100, verbose_name=_('Untertitle'), blank=True)
bodytext = HTMLField(verbose_name=_('Inhalt'), configuration='simple_ckeditor')
image = FilerImageField(verbose_name=_('Bild'), blank=True, null=True)
folder = FilerFolderField(verbose_name=_('Bilder'), blank=True, null=True)
publish_date = models.DateTimeField(verbose_name=_('Veröffentlichungsdatum'), default=timezone.now)
deadline = models.DateTimeField(verbose_name=_('Anmeldeschluss'), blank=True, null=True)
class MemberTask(TranslatableModel):
groups = models.ManyToManyField(Group, verbose_name='Mitglieder Gruppe', related_name='tasks')
image = CroppableFilerImageField(verbose_name='Bild', blank=True, null=True)
cropping = ImageRatioField('image', '1200x800', free_crop=True)
max_num = models.IntegerField(verbose_name=_('max. Formulare'), default=1)
submit_text = models.CharField(max_length=100, verbose_name=_('Formular Button Text'),
default=_('Als gelesen markieren'))
form_bodytext = HTMLField(verbose_name=_('Formular Beschreibung'), configuration='simple_ckeditor', blank=True,
default='<h2 class="reveal reveal_animation">Jetzt anmelden</h2>')
placeholder = PlaceholderField('content')
success_title = models.CharField(verbose_name=_('Bestätigungstitel'), max_length=200,
default=_('Ihre Anmeldung wurde erfasst'))
success_bodytext = HTMLField(verbose_name=_('Bestätigungstext'), configuration='simple_ckeditor')
published = models.BooleanField(verbose_name='Veröffentlicht', default=False)
publish_date = models.DateTimeField(verbose_name='Veröffentlichungsdatum', default=timezone.now)
informed_users = models.ManyToManyField(get_user_model(), verbose_name='Als gelesen markiert von:',
null=True, blank=True)
translations = TranslatedFields(
title=models.CharField(max_length=100, verbose_name=_('Title')),
)
class Meta:
verbose_name = _('Mitglieder Aufgabe')
verbose_name_plural = _('Mitglieder Aufgaben')
verbose_name = 'Mitglieder Aufgabe'
verbose_name_plural = 'Mitglieder Aufgaben'
ordering = ['-publish_date']
def __str__(self):
return self.title
@property
def images(self):
return [x for x in self.folder.files if isinstance(x, ImageModel)]
def get_absolute_url(self):
return reverse_lazy('memberzone:task', args=[self.slug])
@property
def is_expired(self):
return self.deadline and self.deadline <= timezone.now()
@property
def form_class(self):
fields = self.fields.all()
class MyDynamicForm(forms.Form):
def __init__(self, *args, **kwargs):
super(MyDynamicForm, self).__init__(*args, **kwargs)
for f in fields:
self.fields[f.name.replace('-', '_')] = f.form_field
return MyDynamicForm
return reverse_lazy('memberzone:task', args=[self.pk])
class MemberTaskFormField(models.Model):
FIELD_TYPES = [
('text', _('Text Feld (einzeilig)')),
('textarea', _('Text Feld (mehrzeilig)')),
('email', _('E-Mail Feld')),
('radio', _('Auswahlfeld (eine auswahl)')),
('checkbox', _('Auswahlfeld (mehrere auswahlen)')),
]
task = models.ForeignKey(MemberTask, related_name='fields', verbose_name=_('Mitglieder Aufgabe'))
type = models.CharField(max_length=30, choices=FIELD_TYPES)
label = models.CharField(max_length=100, verbose_name=_('Label'))
name = models.SlugField(verbose_name=_('Name'))
choices = models.TextField(verbose_name=_('Auswahlwerte'),
help_text=_(
'Werte die bei einem Auswahlfeld zur verfügung stehen sollen. Ein wert pro Zeile'),
blank=True)
required = models.BooleanField(default=False, verbose_name=_('Pflichtfeld'))
ordering = models.IntegerField(default=50, verbose_name=_('Sortierung'))
class MemberDownloadSection(TranslatableModel):
translations = TranslatedFields(
title=models.CharField(max_length=100, verbose_name='Title')
)
ordering = models.IntegerField(default=50, verbose_name='Sortierung')
class Meta:
verbose_name = _('Formularfeld')
verbose_name_plural = _('Formularfelder')
ordering = ['ordering']
unique_together = ['task', 'name']
def __str__(self):
return self.label
@property
def form_choices(self):
return [(x, x) for x in self.choices.splitlines()]
@property
def form_field(self):
if self.type == 'email':
return forms.EmailField(label=self.label, required=self.required)
elif self.type == 'textarea':
return forms.CharField(label=self.label, required=self.required, widget=forms.Textarea())
elif self.type == 'radio':
return forms.ChoiceField(label=self.label, required=self.required, choices=self.form_choices,
widget=forms.RadioSelect)
elif self.type == 'checkbox':
return forms.MultipleChoiceField(label=self.label, required=self.required, choices=self.form_choices,
widget=forms.CheckboxSelectMultiple)
else:
return forms.CharField(label=self.label, required=self.required)
class MemberTaskRegistration(models.Model):
task = models.ForeignKey(MemberTask, related_name='registrations', verbose_name=_('Mitglieder Aufgabe'))
user = models.ForeignKey(get_user_model(), related_name='registrations')
form_data = models.TextField(verbose_name=_('Form Content'))
cdate = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = _('Mitglieder Aufgabe Registierung')
verbose_name_plural = _('Mitglieder Aufgaben Registierungen')
unique_together = ['user', 'task']
def __str__(self):
return '{} {}'.format(self.user, self.task)
class MemberDownloadSection(models.Model):
title = models.CharField(max_length=100, verbose_name=_('Title'))
ordering = models.IntegerField(default=50, verbose_name=_('Sortierung'))
class Meta:
verbose_name = _('Mitglieder Download Section')
verbose_name_plural = _('Mitglieder Download Sections')
verbose_name = 'Mitglieder Download Section'
verbose_name_plural = 'Mitglieder Download Sections'
ordering = ['ordering']
def __str__(self):
return self.title
class MemberDownloadTag(models.Model):
name = models.CharField(max_length=100, verbose_name=_('Name'))
class MemberDownloadTag(TranslatableModel):
translations = TranslatedFields(
name=models.CharField(max_length=100, verbose_name='Name')
)
class Meta:
verbose_name = _('Mitglieder Download Tag')
verbose_name_plural = _('Mitglieder Download Tags')
verbose_name = 'Mitglieder Download Tag'
verbose_name_plural = 'Mitglieder Download Tags'
def __str__(self):
return self.name
@@ -179,22 +99,24 @@ else:
protected_file_storage = default_storage
class MemberDownloadFile(models.Model):
section = models.ForeignKey(MemberDownloadSection, verbose_name=_('Download Section'), related_name='files')
groups = models.ManyToManyField(Group, verbose_name=_('Mitgliedergruppen'), related_name='files')
tags = models.ManyToManyField(MemberDownloadTag, verbose_name=_('Suchbegriffe'), related_name='files', blank=True,
null=True)
class MemberDownloadFile(TranslatableModel):
section = models.ForeignKey(MemberDownloadSection, verbose_name='Download Section', related_name='files')
groups = models.ManyToManyField(Group, verbose_name='Mitgliedergruppen', related_name='files')
tags = models.ManyToManyField(MemberDownloadTag, verbose_name='Suchbegriffe', related_name='files',
blank=True, null=True)
name = models.CharField(max_length=512, verbose_name=_('Name'), blank=True, null=True)
description = models.TextField(verbose_name=_('Beschreibung'), blank=True, null=True)
file = models.FileField(upload_to='protected_files', max_length=512, storage=protected_file_storage)
translations = TranslatedFields(
name=models.CharField(max_length=512, verbose_name='Name', blank=True, null=True),
description=models.TextField(verbose_name='Beschreibung', blank=True, null=True),
file=models.FileField(upload_to='protected_files', max_length=512, storage=protected_file_storage)
)
ordering = models.IntegerField(default=50, verbose_name=_('Sortierung'))
ordering = models.IntegerField(default=50, verbose_name='Sortierung')
class Meta:
verbose_name = _('Mitglieder Download')
verbose_name_plural = _('Mitglieder Downloads')
ordering = ['ordering', 'name']
verbose_name = 'Mitglieder Download'
verbose_name_plural = 'Mitglieder Downloads'
ordering = ['ordering']
def __str__(self):
return self.label
@@ -212,8 +134,8 @@ class MemberDownloadFile(models.Model):
if self.name:
return self.name
else:
return self.file.name
return os.path.basename(self.file.name)
@property
def tag_list(self):
return ', '.join(list(self.tags.values_list('name', flat=True)))
return ', '.join(list(self.tags.values_list('translations__name', flat=True)))

View File

@@ -0,0 +1,13 @@
{% load i18n %}
<form action="{{ request.path }}" method="post">
{% csrf_token %}
<div class="control__item__fields">
{% for field in form %}
{% include 'project/includes/field.html' with field=field label=True %}
{% endfor %}
</div>
<button class="button button--small">
<span class="button__icon">{% include 'project/assets/tick.svg' %}</span>
<span class="button__text">{% trans 'Speichern' %}</span>
</button>
</form>

View File

@@ -1,16 +0,0 @@
{% load i18n %}
<form action="{% url 'memberzone:change_password' %}" method="post">
{% csrf_token %}
<div class="control__item__fields">
{% include 'project/content/includes/_field.html' with field=form.old_password label=True small=True %}
{% include 'project/content/includes/_field.html' with field=form.new_password1 label=True small=True %}
{% include 'project/content/includes/_field.html' with field=form.new_password2 label=True small=True %}
</div>
<button class="button button--small">
<span class="button__wrapper">
{% include 'project/assets/tick.svg' %}
<b>{% trans 'ändern' %}</b>
</span>
{% include 'project/assets/tick.svg' %}
</button>
</form>

View File

@@ -1,11 +0,0 @@
{% load i18n %}
<div class="control__item__success">
<span class="tag tag--black">{% trans 'Ihr Passwort wurden erfolgreich geändert' %}</span>
<a href="#" class="button button--small control__item__close">
<span class="button__wrapper">
{% include 'project/assets/close.svg' %}
<b>{% trans 'Schliessen' %}</b>
</span>
{% include 'project/assets/close.svg' %}
</a>
</div>

View File

@@ -0,0 +1,8 @@
{% load i18n %}
<div class="control__item__success">
<p>{% trans 'Ihre Informationen wurden erfolgreich angepasst.' %}</p>
<a href="#" class="button button--small control__item__close">
<span class="button__icon">{% include 'project/assets/close.svg' %}</span>
<span class="button__text">{% trans 'Schliessen' %}</span>
</a>
</div>

View File

@@ -1,14 +0,0 @@
<html>
<head>{{ subject }}</head>
<body>
<h1>{{ subject }}</h1>
<hr>
{% for data_set in data %}
<ul>
{% for label, value in data_set %}
<li><strong>{{ label }}:</strong> {{ value }}</li>
{% endfor %}
</ul>
{% endfor %}
</body>
</html>

View File

@@ -1,57 +0,0 @@
{% load i18n static util_tags thumbnail %}
<div id="downloads" class="downloads__frame reveal_self reveal reveal_animation">
<div class="downloads__content">
{% if title != False %}
<h2 class="{% if not light %}white{% endif %} reveal_self reveal reveal_animation">{% trans title %}</h2>
{% endif %}
{% if search %}
<form class="downloads__filter reveal_self reveal reveal_animation" action="{{ request.path }}#downloads" method="get">
<div class="input__frame input__frame--blue input__frame--icon">
<input name="q" {% if request.GET.q %}value="{{ request.GET.q }}"{% endif %} id="downloads_search"
type="text" placeholder="{% trans 'Suchbegriff eingeben' %}">
<button>{% trans 'Suchen' %}{% include 'project/assets/search.svg' %}</button>
</div>
</form>
{% endif %}
{% for section in download_sections %}
<div class="downloads__section reveal_container">
<div class="downloads__section__title{% if flat %} downloads__section__title--flat{% endif %} reveal reveal_animation">
<h3 class="tag{% if flat %} tag--black{% endif %}{% if not light %} white{% endif %}">{{ section.title }}</h3>
</div>
{% include 'project/plugins/content/download_section.html' with instance=section %}
{# <div class="downloads__list reveal reveal_animation">#}
{# {% for file in files %}#}
{# <div class="downloads__item__frame">#}
{# <a target="_blank" href="{{ file.file.url }}" class="downloads__item">#}
{# <div class="downloads__item__main">#}
{# <div class="downloads__item__content reveal reveal_animation">#}
{# <span class="downloads__item__icon tag">#}
{# {% include 'project/assets/download.svg' %}#}
{# {{ file.file.name|split:'.'|last }}#}
{# </span>#}
{# {% if file.thumbnail %}#}
{# <img class="downloads__item__thumbnail"#}
{# src="{{ file.thumbnail.url }}">#}
{# {% elif file.file.name|split:'.'|last == 'pdf' %}#}
{# <img class="downloads__item__thumbnail"#}
{# src="{% download_thumbnail file %}">#}
{# {% else %}#}
{# {% thumbnail file.file 118x167 crop=True as thumb %}#}
{# {% static 'img/pdf_default.jpg' as static %}#}
{# <img class="downloads__item__thumbnail"#}
{# src="{{ thumb.url|default:static }}">#}
{# {% endif %}#}
{# </div>#}
{# </div>#}
{# <span class="p downloads__item__text">{{ file }}</span>#}
{# <span class="downloads__item__tags">{{ file.tag_list }}</span>#}
{# </a>#}
{# </div>#}
{# {% endfor %}#}
{# </div>#}
</div>
{% endfor %}
</div>
</div>

View File

@@ -1,8 +0,0 @@
<div class="input__frame{% if blue %} input__frame--blue{% endif %}{% if label %} input__frame--label{% else %} input__frame--no-label{% endif %}{% if small %} input__frame--small{% endif %}"
{% if hidden %}style="display: none"{% endif %}>
<label for="id_{{ field.name }}" class="p"><span>{{ field.label }}:</span></label>
{{ field }}
{% if field.errors %}
<span class="tag tag--light input__errors">{{ field.errors.0 }}</span>
{% endif %}
</div>

View File

@@ -1,160 +1,82 @@
{% extends 'main.html' %}
{% load i18n cms_tags thumbnail %}
{% load i18n static task_tags %}
{% load i18n static %}
{% block title %}{% trans 'Mitgliederbereich' %}{% endblock %}
{% block content %}
<div class="content__frame">
{% include 'project/includes/content_intro.html' %}
<div class="content__intro reveal_container reveal_self reveal reveal_animation image">
<div class="content__intro__content reveal reveal_animation">
<h1>{% trans 'Grüezi, ' %}{{ request.user.profile.full_name }}</h1>
<p>{% trans 'Willkommen in Ihrem persönlichen Portal der Tagesschule Elementa' %}</p>
<a href="{% url 'memberzone:logout' %}" class="button">
<span class="button__icon">{% include 'project/assets/arrow-left-long.svg' %}</span>
<span class="button__text">{% trans 'Logout' %}</span>
</a>
</div>
<div class="content__intro__image scroll reveal reveal_animation" data-ease-multiplier="-2"
style="background-image: url({% static 'img/memberzone_background.jpg' %})"></div>
</div>
<div class="content__container">
<div class="content__main">
<div class="control_panel reveal_self reveal reveal_animation">
<div class="control_panel__content">
<div class="todo">
<div class="control_panel__content__item">
<h2 class="reveal_self reveal reveal_animation">{% trans 'Aktuell' %}</h2>
<div id="todo" class="load__frame">
<div class="load__main">
<ul class="control__list reveal_container">
{% if open_tasks %}
{% for object in open_tasks %}
<li class="data_id_{{ forloop.counter0 }} reveal reveal_animation">
<a href="{{ object.get_absolute_url }}"
class="p control__item control__item--arrow control__item--status {{ object|task_status:request.user }}">
<span class="control__item__title">
<span class="control__item__status">
{% if object.is_expired %}
{% include 'project/assets/close.svg' %}
{% else %}
{% include 'project/assets/tick.svg' %}
{% endif %}
</span>
{{ object.title }}
<span class="control__item__arrow">
{% include 'project/assets/arrow-bottom.svg' %}
</span>
{% for object in object_list %}
<li class="data_id_{{ forloop.counter0 }} reveal reveal_animation">
<a href="{{ object.get_absolute_url }}"
class="p control__item control__item--arrow control__item--status {% if request.user in object.informed_users.all %}control__item--status--active{% endif %}">
<span class="control__item__title">
<span class="control__item__status">
{% if object.is_expired %}
{% include 'project/assets/close.svg' %}
{% else %}
{% include 'project/assets/tick.svg' %}
{% endif %}
</span>
</a>
</li>
{% endfor %}
{% else %}
{% for object in object_list %}
<li class="data_id_{{ forloop.counter0 }} reveal reveal_animation">
<a href="{{ object.get_absolute_url }}"
class="p control__item control__item--arrow control__item--status {{ object|task_status:request.user }}">
<span class="control__item__title">
<span class="control__item__status">
{% if object.is_expired %}
{% include 'project/assets/close.svg' %}
{% else %}
{% include 'project/assets/tick.svg' %}
{% endif %}
</span>
{{ object.title }}
<span class="control__item__arrow">
{% include 'project/assets/arrow-bottom.svg' %}
</span>
{{ object.title }}
<span class="control__item__arrow">
{% include 'project/assets/arrow-right.svg' %}
</span>
</a>
</li>
{% endfor %}
{% endif %}
</span>
</a>
</li>
{% endfor %}
</ul>
{% if page_obj.has_next or open_tasks and paginator.count > 0 %}
{% if page_obj.has_next or paginator.count > 0 and open_object_list %}
<div class="load__replace data_id_3 reveal_self reveal reveal_animation">
<a href="{% url 'memberzone:overview' %}?page=
{% if open_tasks %}{{ page_obj.start_index }}{% else %}{{ page_obj.next_page_number }}{% endif %}"
<a href="{% spaceless %}{% url 'memberzone:overview' %}?page=
{% if open_object_list %}{{ page_obj.start_index }}{% else %}{{ page_obj.next_page_number }}{% endif %}{% endspaceless %}"
class="button button--load list__button button--small">
<span class="button__wrapper">
{% include 'project/assets/dots.svg' %}
<b>{% trans 'Ältere laden' %}</b>
</span>
{% include 'project/assets/dots.svg' %}
<span class="button__icon">{% include 'project/assets/dots.svg' %}</span>
<span class="button__text">{% trans 'Ältere laden' %}</span>
</a>
</div>
{% endif %}
</div>
</div>
</div>
<div class="settings">
<div class="control_panel__content__item">
<h2 class="reveal_self reveal reveal_animation">{% trans 'Einstellungen' %}</h2>
<ul class="control__list reveal_container">
<li class="data_id_0 reveal reveal_animation">
<div class="p control__item control__item--button">
<span class="control__item__title">
{% trans 'Benutzerdaten' %}
<a href="#" data-href="{% url 'memberzone:profile_edit' %}"
class="button button--small button--load control__item__open">
<span class="button__wrapper">
{% include 'project/assets/dots.svg' %}
<b>{% trans 'Bearbeiten' %}</b>
</span>
{% include 'project/assets/dots.svg' %}
</a>
<a href="#" class="button button--small button--ghost control__item__close">
<span class="button__wrapper">
{% include 'project/assets/close.svg' %}
<b>{% trans 'Abbrechen' %}</b>
</span>
{% include 'project/assets/close.svg' %}
</a>
</span>
<div class="control__item__content">
<div class="control__item__content__main">
</div>
</div>
</div>
</li>
<li class="data_id_1 reveal reveal_animation">
<div class="p control__item control__item--button">
<span class="control__item__title">
{% trans 'Passwort' %}
<a href="#" data-href="{% url 'memberzone:change_password' %}"
class="button button--small button--load control__item__open">
<span class="button__wrapper">
{% include 'project/assets/dots.svg' %}
<b>{% trans 'Bearbeiten' %}</b>
</span>
{% include 'project/assets/dots.svg' %}
</a>
<a href="#" class="button button--small button--ghost control__item__close">
<span class="button__wrapper">
{% include 'project/assets/close.svg' %}
<b>{% trans 'Abbrechen' %}</b>
</span>
{% include 'project/assets/close.svg' %}
</a>
</span>
<div class="control__item__content">
<div class="control__item__content__main">
</div>
</div>
</div>
</li>
{% if request.user.company_responsible %}
<li class="data_id_2 reveal reveal_animation">
<div class="p control__item control__item--button">
{% for settings_title, settings_url in settings %}
<li class="reveal reveal_animation data_delay_{{ forloop.counter0 }}">
<div class="control__item control__item--button">
<span class="control__item__title">
{% trans 'Firmendaten' %}
<a href="#" data-href="{% url 'memberzone:company_edit' %}"
class="button button--small button--load control__item__open">
<span class="button__wrapper">
{% include 'project/assets/dots.svg' %}
<b>{% trans 'Bearbeiten' %}</b>
</span>
{% include 'project/assets/dots.svg' %}
{{ settings_title }}
<a href="#" data-href="{{ settings_url }}"
class="button button--small control__item__open">
<span class="button__icon">{% include 'project/assets/dots.svg' %}</span>
<span class="button__text">{% trans 'Ändern' %}</span>
</a>
<a href="#"
class="button button--small button--ghost control__item__close">
<span class="button__wrapper">
{% include 'project/assets/close.svg' %}
<b>{% trans 'Abbrechen' %}</b>
</span>
{% include 'project/assets/close.svg' %}
<span class="button__icon">{% include 'project/assets/close.svg' %}</span>
<span class="button__text">{% trans 'Abbrechen' %}</span>
</a>
</span>
<div class="control__item__content">
@@ -163,14 +85,33 @@
</div>
</div>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</div>
{% include 'memberzone/includes/_downloads.html' with search=True title='Downloads' %}
<div id="downloads" class="downloads__frame reveal_self reveal reveal_animation">
<h2 class="reveal_self reveal reveal_animation">{% trans 'Downloads' %}</h2>
<form class="downloads__filter reveal_self reveal reveal_animation"
action="{{ request.path }}#downloads" method="get">
<div class="form__field form__field--icon">
<input name="q" {% if request.GET.q %}value="{{ request.GET.q }}"{% endif %}
id="downloads_search"
type="text" placeholder="{% trans 'Suchbegriff eingeben' %}">
<button>{% trans 'Suchen' %}{% include 'project/assets/search.svg' %}</button>
</div>
</form>
{% for section in download_sections %}
<div class="downloads__section reveal_container">
<div class="downloads__section__title{% if flat %} downloads__section__title--flat{% endif %} reveal reveal_animation">
<h3>{{ section.title }}</h3>
</div>
{% include 'project/plugins/content/download_section.html' with instance=section %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -1,17 +0,0 @@
{% load i18n %}
<form action="{% url 'memberzone:profile_edit' %}" method="post">
{% csrf_token %}
<div class="control__item__fields">
{% include 'memberzone/includes/_field.html' with field=form.gender label=True small=True %}
{% include 'memberzone/includes/_field.html' with field=form.title label=True small=True %}
{% include 'memberzone/includes/_field.html' with field=form.first_name label=True small=True %}
{% include 'memberzone/includes/_field.html' with field=form.last_name label=True small=True %}
</div>
<button class="button button--small">
<span class="button__wrapper">
{% include 'project/assets/tick.svg' %}
<b>{% trans 'Speichern' %}</b>
</span>
{% include 'project/assets/tick.svg' %}
</button>
</form>

View File

@@ -1,11 +0,0 @@
{% load i18n %}
<div class="control__item__success">
<span class="tag tag--black">{% trans 'Ihre Benutzerdaten wurden erfolgreich geändert' %}</span>
<a href="#" class="button button--small control__item__close">
<span class="button__wrapper">
{% include 'project/assets/close.svg' %}
<b>{% trans 'Schliessen' %}</b>
</span>
{% include 'project/assets/close.svg' %}
</a>
</div>

View File

@@ -1,139 +1,44 @@
{% extends 'project/content.html' %}
{% load i18n static thumbnail task_tags %}
https://source.unsplash.com/random/1200x900
{% load i18n thumbnail cms_tags %}
{% block body_class %}header-close{% endblock %}
{% block header_menu_url %}{% url 'memberzone:overview' %}{% endblock %}
{% block title %}{{ object.title }}{% endblock %}
{% block intro_class %}intro--image{% endblock %}
{% block intro_image %}{% if object.image %}
{% thumbnail object.image "1200x900" crop="center" subject_location=object.image.subject_location %}
{% endif %}{% endblock %}
{% block content_content %}
<div class="text text--full text--narrow reveal_container">
<div class="text__content">
<div class="text__content__frame">
<div class="text__content__main">{{ object.bodytext | add_animation_classes | safe }}</div>
</div>
{% block content_intro %}
<div class="content__intro reveal_container reveal_self reveal reveal_animation{% if object.image %} image{% endif %}">
<div class="content__intro__content reveal reveal_animation">
<h1>{{ object.title }}</h1>
<a href="{% url 'memberzone:overview' %}" class="button">
<span class="button__icon">{% include 'project/assets/arrow-left-long.svg' %}</span>
<span class="button__text">{% trans 'Zurück zur Übersicht' %}</span>
</a>
</div>
{% if object.image %}
{% thumbnail object.image 1600x800 box=object.cropping crop detail as thumb %}
<div class="content__intro__image scroll reveal reveal_animation" data-ease-multiplier="-2"
style="background-image: url({{ thumb.url }})"></div>
{% endif %}
</div>
{% endblock %}
{% include 'project/content/includes/_grid.html' with grid=grid last=True %}
{% block navigation_title %}{{ object.title }}{% endblock %}
<div id="form"></div>
<div class="text text--full text--narrow reveal_container">
<div class="text__content">
<div class="text__content__frame">
<div class="text__content__main">
{% if formset and not object.is_expired %}
{{ object.form_bodytext | add_animation_classes | safe }}
{% if formset.errors %}
<span class="tag tag--light input__errors reveal reveal_animation">
{% trans 'Bitte korrigieren Sie die markierten Felder.' %}
</span>
{% endif %}
{% if formset.non_form_errors %}
<span class="tag tag--light input__errors reveal reveal_animation">
{{ formset.non_form_errors }}
</span>
{% endif %}
<form action="{% url 'memberzone:task' object.slug %}" method="post"
class="task__form text__content__form reveal reveal_animation {% if formset.errors %}errors{% endif %}"
data-formset-prefix="{{ formset.prefix }}">
{% csrf_token %}
{{ formset.management_form }}
{% block content_main %}
{% render_placeholder object.placeholder language LANGUAGE_CODE %}
<div data-formset-body>
{% for form in formset %}
<fieldset data-formset-form>
{% if object.max_num > 1 %}
<div class="fieldset__title">
<h3 class="tag" data-id="{{ forloop.counter }}">{{ forloop.counter }}.
Person</h3>
{% if forloop.counter0 > 0 %}
<a class="tag" data-formset-delete-button>
{% include 'project/assets/close.svg' %}
{% trans 'Entfernen' %}
</a>
{% endif %}
</div>
{% endif %}
<form action="{{ request.path }}" method="post" class="task__form reveal_self reveal reveal_animation">
{% csrf_token %}
{% if form.non_field_errors %}
<span class="tag tag--light input__errors">
{{ formset.non_field_errors }}
</span>
{% endif %}
{% for field in form %}
{% if field.name == 'DELETE' %}
{% include 'project/content/includes/_field.html' with field=field label=True hidden=True %}
{% else %}
{% include 'project/content/includes/_field.html' with field=field label=True %}
{% endif %}
{% endfor %}
</fieldset>
{% endfor %}
</div>
<script type="form-template" data-formset-empty-form>
<fieldset data-formset-form>
<div class="fieldset__title">
<h3 class="tag" data-id="{{ formset.empty_form.prefix }}">%(id). Person</h3>
<a class="tag" data-formset-delete-button>
{% include 'project/assets/close.svg' %}
{% trans 'Entfernen' %}
</a>
</div>
{% for field in formset.empty_form %}
{% if field.name == 'DELETE' %}
{% include 'project/content/includes/_field.html' with field=field label=True hidden=True %}
{% else %}
{% include 'project/content/includes/_field.html' with field=field label=True %}
{% endif %}
{% endfor %}
</fieldset>
</script>
<div class="form__controls">
<button class="button">
<span class="button__wrapper">
{% include 'project/assets/arrow-right-long.svg' %}
<b>{{ object.submit_text }}</b>
</span>
{% include 'project/assets/arrow-right-long.svg' %}
</button>
{% if object.max_num > 1 %}
<a class="button button--light" data-formset-add>
<span class="button__wrapper">
{% include 'project/assets/plus.svg' %}
<b>{% trans 'Weitere Person hinzufügen' %}</b>
</span>
</a>
{% endif %}
</div>
</form>
{% else %}
{% if object.is_expired %}
<h3 class="reveal reveal_animation">{% trans 'Die Anmeldungsfrist abgelaufen' %}</h3>
<p class="reveal reveal_animation">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et
accusam et
</p>
{% else %}
<h3 class="reveal reveal_animation">{% trans "Bereits abgeschlossen" %}</h3>
<p class="reveal reveal_animation">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et
accusam et
</p>
{% endif %}
{% endif %}
</div>
</div>
<div class="form__submit">
<a href="{% url 'memberzone:overview' %}" class="button button--ghost">
<span class="button__icon">{% include 'project/assets/arrow-left-long.svg' %}</span>
<span class="button__text">{% trans 'Zurück zur Übersicht' %}</span>
</a>
{% if not request.user in object.informed_users.all %}
<button class="button">
<span class="button__icon">{% include 'project/assets/tick.svg' %}</span>
<span class="button__text">{% trans 'Als gelesen markieren' %}</span>
</button>
{% endif %}
</div>
</div>
</form>
{% endblock %}

View File

@@ -1,20 +0,0 @@
{% extends 'project/dialog.html' %}
{% load i18n static %}
{% block extra_meta %}
<meta name="robots" content="noindex, nofollow">
{% endblock %}
{% block dialog_content %}
<div class="dialog__text reveal_self reveal reveal_animation">
{{ object.success_bodytext | safe }}
<a href="{% url 'memberzone:overview' %}" class="button">
<span class="button__wrapper">
{% include 'project/assets/arrow-right-long.svg' %}
<b>{% trans 'Zur Accountübersicht' %}</b>
</span>
{% include 'project/assets/arrow-right-long.svg' %}
</a>
</div>
{% endblock %}

View File

@@ -1,16 +1,36 @@
{% extends 'main.html' %}
{% extends 'project/dialog.html' %}
{% load i18n %}
{% block title %}{% trans 'Mitgliederbereich' %}{% endblock %}
{% block content %}
<div class="content__frame">
<div class="content__container">
<div class="content__main content__main--center">
<form action="" method="post">
{% csrf_token %}
{{ form }}
</form>
</div>
</div>
</div>
{% block extra_meta %}
<meta name="robots" content="noindex, nofollow"/>
{% endblock %}
{% block dialog %}
<h2 class="reveal_self reveal reveal_animation">{% trans 'Login' %}</h2>
<p class="reveal_self reveal reveal_animation section__text">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
</p>
<form class="reveal_self reveal reveal_animation" method="post" action=".">
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p class="form__errors reveal_self reveal reveal_animation">{{ error }}</p>
{% endfor %}
{% endif %}
{% csrf_token %}
{% for field in form %}
{% include 'project/includes/field.html' with field=field %}
{% endfor %}
<div class="form__submit reveal_self reveal reveal_animation">
<button type="submit" class="button">
<span class="button__icon">{% include 'project/assets/arrow-right-long.svg' %}</span>
<span class="button__text">{% trans 'Login' %}</span>
</button>
</div>
</form>
{% endblock %}

View File

@@ -1,34 +0,0 @@
import lxml.html
from django import template
from django.template.defaultfilters import stringfilter
from memberzone.models import MemberTaskRegistration
register = template.Library()
@register.filter(name='task_status')
def task_user_status(task, user):
try:
MemberTaskRegistration.objects.get(task=task, user=user)
except MemberTaskRegistration.DoesNotExist:
if task.is_expired:
return 'control__item--status--expired'
else:
return ''
else:
return 'control__item--status--active'
@register.filter
@stringfilter
def add_animation_classes(input_html):
document = lxml.html.fromstring('<div>{}</div>'.format(input_html))
for el in document.xpath('//p|ul|ol|h2|h3'):
classes = el.attrib.get('class', '').split(' ')
if 'reveal' not in classes:
classes.append('reveal')
if 'reveal_animation' not in classes:
classes.append('reveal_animation')
el.attrib['class'] = ' '.join(classes)
return lxml.html.tostring(document)[5:-6]

View File

@@ -10,35 +10,29 @@ from memberzone.forms import LoginForm
from memberzone.views import OverviewView, MemberTaskDetailView, MemberTaskDetailSuccessView, ProfileEditView
urlpatterns = [
url(_(r'^login/$'), LoginView.as_view(
success_url=reverse_lazy('memberzone:overview'),
form_class=LoginForm
), name='login'),
url(_(r'^logout/$'), LogoutView.as_view(next_page='login'), name='logout'),
url(_(r'^login/$'), LoginView.as_view(form_class=LoginForm), name='login'),
url(_(r'^logout/$'), LogoutView.as_view(next_page=reverse_lazy('memberzone:overview')), name='logout'),
url(_(r'^account/change/password/$'), login_required(PasswordChangeView.as_view(
template_name='memberzone/change_password.html',
template_name='memberzone/change_form.html',
success_url=reverse_lazy('memberzone:change_password_done')
), login_url=reverse_lazy('memberzone:login')), name='change_password'),
url(_(r'^account/change/password/succeeded/$'), login_required(TemplateView.as_view(
template_name='memberzone/change_password_done.html'
url(_(r'^account/change/password/success/$'), login_required(TemplateView.as_view(
template_name='memberzone/change_success.html'
), login_url=reverse_lazy('memberzone:login')), name='change_password_done'),
url(_(r'^account/edit/$'), login_required(ProfileEditView.as_view(
url(_(r'^profile/edit/$'), login_required(ProfileEditView.as_view(
), login_url=reverse_lazy('memberzone:login')), name='profile_edit'),
url(_(r'^account/edit/succeeded/$'), login_required(TemplateView.as_view(
template_name='memberzone/profile_edit_done.html'
url(_(r'^profile/edit/success/$'), login_required(TemplateView.as_view(
template_name='memberzone/change_success.html'
), login_url=reverse_lazy('memberzone:login')), name='profile_edit_done'),
url(_(r'^task/(?P<slug>[\w-]+)/$'), login_required(MemberTaskDetailView.as_view(
url(_(r'^task/(?P<pk>\d+)/$'), login_required(MemberTaskDetailView.as_view(
), login_url=reverse_lazy('memberzone:login')), name='task'),
url(_(r'^task/(?P<slug>[\w-]+)/success/$'),
login_required(MemberTaskDetailSuccessView.as_view(), login_url=reverse_lazy('memberzone:login')),
name='task_success'),
url(_(r'^overview/$'), login_required(OverviewView.as_view(), login_url=reverse_lazy('memberzone:login')),
name='overview'),
]

View File

@@ -1,36 +1,26 @@
import json
from django.conf import settings
from django.contrib.auth.forms import SetPasswordForm
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.views import LoginView as DjangoLoginView
from django.contrib.sites.shortcuts import get_current_site
from django.core.mail import EmailMessage
from django.db.models import Q
from django.forms import formset_factory
from django.http import HttpResponseRedirect
from django.shortcuts import resolve_url
from django.template.loader import render_to_string
from django.urls import reverse, reverse_lazy
from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.utils import timezone
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.translation import ugettext_lazy as _
from django.views.generic import UpdateView, ListView, DetailView, FormView
from django.views.generic import UpdateView, ListView, DetailView
from memberzone.models import MemberTask, MemberTaskRegistration, MemberDownloadFile, Profile
from memberzone.forms import ProfileEditForm
from memberzone.models import MemberTask, MemberDownloadFile
class MemeberTaskQuerysetMixin(object):
def get_queryset(self):
return MemberTask.objects.filter(groups__in=self.request.user.groups.all()).distinct()
queryset = MemberTask.objects.filter(groups__in=self.request.user.groups.all())
if not self.request.user.is_superuser:
queryset = queryset.filter(published=True)
return queryset
class OverviewView(MemeberTaskQuerysetMixin, ListView):
template_name = 'memberzone/overview.html'
open_tasks = None
paginate_by = 3
paginate_by = 5
def get_title(self):
return _('Grüezi, {first_name} {last_name}').format(
@@ -50,106 +40,46 @@ class OverviewView(MemeberTaskQuerysetMixin, ListView):
sections[file.section_id]['items'].append(file)
sections_list = [{'title': x['section'].title, 'items': x['items'], 'ordering': x['section'].ordering} for x in
sections.values()]
sections.values()]
return sorted(sections_list, key=lambda x: x['ordering'])
def get_queryset(self):
queryset = super(OverviewView, self).get_queryset()
return queryset.exclude(pk__in=self.get_open_tasks().values_list('pk', flat=True))
return queryset.filter(informed_users__in=[self.request.user])
def get_open_tasks(self):
yesterday = timezone.now() - timezone.timedelta(days=1)
all_user_registrations = MemberTaskRegistration.objects.filter(user=self.request.user, cdate__lte=yesterday)
queryset = MemeberTaskQuerysetMixin.get_queryset(self)
queryset.exclude(registrations__in=all_user_registrations).order_by('-registrations__cdate')
queryset = MemeberTaskQuerysetMixin.get_queryset(self).exclude(informed_users__in=[self.request.user])
return queryset
def get_settings(self):
settings = (
(_('Benutzerdaten'), reverse_lazy('memberzone:profile_edit')),
(_('Passwort'), reverse_lazy('memberzone:change_password')),
)
return settings
def get_context_data(self, **kwargs):
context = super(OverviewView, self).get_context_data(**kwargs)
context.update({
'download_sections': self.get_download_sections(),
'open_tasks': None if self.request.GET.get(self.page_kwarg, None) else self.get_open_tasks(),
'settings': self.get_settings()
})
self.open_tasks = self.get_open_tasks()
if not self.request.GET.get(self.page_kwarg, None) and self.open_tasks.count() > 0:
context.update({
'object_list': self.open_tasks,
'open_object_list': True
})
return context
class MemberTaskDetailView(MemeberTaskQuerysetMixin, DetailView):
template_name = 'memberzone/task.html'
model = MemberTask
def get_title(self):
return self.object.title
def get_description(self):
return self.object.sub_title
def get_formset(self):
try:
MemberTaskRegistration.objects.get(task=self.object, user=self.request.user)
except MemberTaskRegistration.DoesNotExist:
MemeberTaskFormset = formset_factory(
self.object.form_class,
extra=0,
min_num=1,
max_num=self.object.max_num,
can_delete=True
)
formset_kwargs = {}
if self.request.method == 'POST':
formset_kwargs.update({
'data': self.request.POST
})
return MemeberTaskFormset(**formset_kwargs)
else:
return None
def formset_valid(self, formset):
registration = MemberTaskRegistration.objects.create(
task=self.object,
user=self.request.user,
form_data=json.dumps(formset.cleaned_data)
)
if registration.task.fields.count() > 0:
self.send_confirmation_email(registration=registration)
return HttpResponseRedirect(reverse('memberzone:task_success', args=[self.object.slug]))
def formset_invalid(self, formset):
return self.render_to_response(context=self.get_context_data(formset=formset, object=self.object))
def get(self, request, *args, **kwargs):
self.object = self.get_object()
formset = self.get_formset()
return self.render_to_response(context=self.get_context_data(formset=formset, object=self.object))
def send_confirmation_email(self, registration):
subject = _('Anmeldebestätigung: {}').format(registration.task.title)
confirmation_data = []
for data_set in json.loads(registration.form_data):
confirmation_data_set = []
for field in registration.task.fields.all():
value = data_set.get(field.name.replace('-', '_'), '')
if isinstance(value, list):
value = ','.join(value)
confirmation_data_set.append((field.label, value,))
confirmation_data.append(confirmation_data_set)
message = render_to_string('memberzone/email/member_registration_confirmation_email.html', {
'data': confirmation_data,
'subject': subject,
})
msg = EmailMessage(subject, message, settings.DEFAULT_FROM_EMAIL, to=[registration.user.email])
msg.content_subtype = "html"
# msg.send()
def post(self, request, *args, **kwargs):
self.object = self.get_object()
formset = self.get_formset()
if formset.is_valid():
return self.formset_valid(formset)
else:
return self.formset_invalid(formset)
self.get_object().informed_users.add(self.request.user)
return redirect('memberzone:overview')
class MemberTaskDetailSuccessView(MemeberTaskQuerysetMixin, DetailView):
@@ -161,9 +91,8 @@ class MemberTaskDetailSuccessView(MemeberTaskQuerysetMixin, DetailView):
class ProfileEditView(UpdateView):
model = Profile
fields = ['first_name', 'last_name', 'street', 'zip', 'place', 'email']
template_name = 'memberzone/profile_edit.html'
form_class = ProfileEditForm
template_name = 'memberzone/change_form.html'
success_url = reverse_lazy('memberzone:profile_edit_done')
def get_object(self, queryset=None):

View File

@@ -79,36 +79,38 @@
{% endfor %}
</ul>
{% if notification %}
<a href="#" class="header__button header__button--notification data_id_1">
{% trans 'Aktuell' %}
{% block header_items %}
{% if notification %}
<a href="#" class="header__button header__button--notification data_id_1">
{% trans 'Aktuell' %}
<span class="header__button__icon">
{% include 'project/assets/bell.svg' %}
</span>
</a>
{% endif %}
<a href="#" class="header__button header__button--search data_id_2">
{% trans 'Suche' %}
<span class="header__button__icon">
{% include 'project/assets/bell.svg' %}
{% include 'project/assets/search.svg' %}
</span>
</a>
{% endif %}
<a href="#" class="header__button header__button--search data_id_2">
{% trans 'Suche' %}
<span class="header__button__icon">
{% include 'project/assets/search.svg' %}
</span>
</a>
{% url 'search' as search_url %}
{% with request.get_full_path as current_url %}
<a href="{% if search_url in current_url %}/{{ LANGUAGE_CODE }}/{% else %}{{ current_url }}{% endif %}"
class="event header__button header__button--navigation data_id_3">
{% trans 'Menü' %}
<span class="header__button__icon">
{% include 'project/assets/menu.svg' %}
</span>
</a>
{% endwith %}
{% url 'search' as search_url %}
{% with request.get_full_path as current_url %}
<a href="{% if search_url in current_url %}/{{ LANGUAGE_CODE }}/{% else %}{{ current_url }}{% endif %}"
class="event header__button header__button--navigation data_id_3">
{% trans 'Menü' %}
<span class="header__button__icon">
{% include 'project/assets/menu.svg' %}
</span>
</a>
{% endwith %}
<div class="header__navigation">
{% include 'project/includes/meta_navigation.html' %}
</div>
<div class="header__navigation">
{% include 'project/includes/meta_navigation.html' %}
</div>
{% endblock %}
</div>
<div id="canvas">

View File

@@ -1,4 +0,0 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M31.4366634,9.44202305 C32.0209679,8.85475847 32.9707124,8.85235889 33.557977,9.43666344 C34.1452415,10.020968 34.1476411,10.9707124 33.5633366,11.557977 L18.6389421,26.557977 C18.0546323,27.1452468 17.1048775,27.1476404 16.517615,26.5633231 L1.44200954,11.5633232 C0.85475238,10.9790112 0.852364866,10.0292667 1.43667688,9.44200954 C2.02098889,8.85475238 2.97073336,8.85236487 3.55799051,9.43667688 L17.5702593,23.3786729 L31.4366634,9.44202305 Z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 626 B

View File

@@ -0,0 +1,5 @@
<svg width="50px" height="35px" viewBox="0 0 50 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<polygon
points="7.0332611 16 48.75 16 48.75 19 6.95202028 19 20.3913601 32.4393398 18.2700398 34.5606602 1.25 17.5406204 18.3512806 0.439339828 20.4726009 2.56066017"></polygon>
</svg>

After

Width:  |  Height:  |  Size: 351 B

View File

@@ -1,4 +1,5 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M26.557977,31.4366634 C27.1452415,32.0209679 27.1476411,32.9707124 26.5633366,33.557977 C25.979032,34.1452415 25.0292876,34.1476411 24.442023,33.5633366 L9.44202305,18.6389421 C8.85475319,18.0546323 8.85235962,17.1048775 9.43667688,16.517615 L24.4366768,1.44200954 C25.0209888,0.85475238 25.9707333,0.852364866 26.5579905,1.43667688 C27.1452476,2.02098889 27.1476351,2.97073336 26.5633231,3.55799051 L12.6213271,17.5702593 L26.557977,31.4366634 Z"></path>
<polygon
points="12.1313402 17.5406204 27.0300596 32.4393398 24.9087393 34.5606602 7.88869954 17.5406204 24.9899801 0.439339828 27.1113005 2.56066017"></polygon>
</svg>

Before

Width:  |  Height:  |  Size: 625 B

After

Width:  |  Height:  |  Size: 334 B

View File

@@ -1,6 +1,5 @@
<svg width="50px" height="35px" viewBox="0 0 50 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M32.442023,3.56333662 C31.8547585,2.97903206 31.8523589,2.02928763 32.4366634,1.44202305 C33.020968,0.854758464 33.9707124,0.852358886 34.557977,1.43666344 L49.557977,16.3610579 C50.1452468,16.9453677 50.1476404,17.8951225 49.5633231,18.482385 L34.5633232,33.5579905 C33.9790112,34.1452476 33.0292667,34.1476351 32.4420095,33.5633231 C31.8547524,32.9790111 31.8523649,32.0292666 32.4366769,31.4420095 L46.3786729,17.4297407 L32.442023,3.56333662 Z"
id="arrow" fill-rule="nonzero"></path>
<rect id="line" x="0" y="16" width="48" height="3" rx="1.5"></rect>
<polygon
points="42.9680397 16 29.5286999 2.56066017 31.6500202 0.439339828 48.7513008 17.5406204 31.731261 34.5606602 29.6099407 32.4393398 43.0492805 19 1.24869919 19 1.24869919 16"></polygon>
</svg>

Before

Width:  |  Height:  |  Size: 739 B

After

Width:  |  Height:  |  Size: 367 B

View File

@@ -1,4 +1,5 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M9.44202305,3.56333662 C8.85475847,2.97903206 8.85235889,2.02928763 9.43666344,1.44202305 C10.020968,0.854758465 10.9707124,0.852358887 11.557977,1.43666344 L26.557977,16.3610579 C27.1452468,16.9453677 27.1476404,17.8951225 26.5633231,18.482385 L11.5633232,33.5579905 C10.9790112,34.1452476 10.0292667,34.1476351 9.44200954,33.5633231 C8.85475238,32.9790111 8.85236487,32.0292666 9.43667688,31.4420095 L23.3786729,17.4297407 L9.44202305,3.56333662 Z"></path>
<polygon
points="22.8686598 17.5406204 7.88869954 2.56066017 10.0100199 0.439339828 27.1113005 17.5406204 10.0912607 34.5606602 7.96994036 32.4393398"></polygon>
</svg>

Before

Width:  |  Height:  |  Size: 628 B

After

Width:  |  Height:  |  Size: 334 B

View File

@@ -1,7 +1,5 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M8.80761184,6.1862915 L29.3137085,26.6923882 C29.8994949,27.2781746 29.8994949,28.2279221 29.3137085,28.8137085 C28.7279221,29.3994949 27.7781746,29.3994949 27.1923882,28.8137085 L6.6862915,8.30761184 C6.10050506,7.72182541 6.10050506,6.77207794 6.6862915,6.1862915 C7.27207794,5.60050506 8.22182541,5.60050506 8.80761184,6.1862915 Z"
class="line-left"></path>
<path d="M6.6862915,26.6923882 L27.1923882,6.1862915 C27.7781746,5.60050506 28.7279221,5.60050506 29.3137085,6.1862915 C29.8994949,6.77207794 29.8994949,7.72182541 29.3137085,8.30761184 L8.80761184,28.8137085 C8.22182541,29.3994949 7.27207794,29.3994949 6.6862915,28.8137085 C6.10050506,28.2279221 6.10050506,27.2781746 6.6862915,26.6923882 Z"
class="line-right"></path>
<polygon
points="17.5 15.3786797 27.6621477 5.21653197 29.783468 7.33785231 19.6213203 17.5 29.783468 27.6621477 27.6621477 29.783468 17.5 19.6213203 7.33785231 29.783468 5.21653197 27.6621477 15.3786797 17.5 5.21653197 7.33785231 7.33785231 5.21653197"></polygon>
</svg>

Before

Width:  |  Height:  |  Size: 925 B

After

Width:  |  Height:  |  Size: 437 B

View File

@@ -1,6 +1,4 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<circle class="left" cx="7.5" cy="17.5" r="2"></circle>
<circle class="middle" cx="17.5" cy="17.5" r="2"></circle>
<circle class="right" cx="27.5" cy="17.5" r="2"></circle>
<path d="M3.5,20.3 C1.9536027,20.3 0.7,19.0463973 0.7,17.5 C0.7,15.9536027 1.9536027,14.7 3.5,14.7 C5.0463973,14.7 6.3,15.9536027 6.3,17.5 C6.3,19.0463973 5.0463973,20.3 3.5,20.3 Z M17.5,20.3 C15.9536027,20.3 14.7,19.0463973 14.7,17.5 C14.7,15.9536027 15.9536027,14.7 17.5,14.7 C19.0463973,14.7 20.3,15.9536027 20.3,17.5 C20.3,19.0463973 19.0463973,20.3 17.5,20.3 Z M31.5,20.3 C29.9536027,20.3 28.7,19.0463973 28.7,17.5 C28.7,15.9536027 29.9536027,14.7 31.5,14.7 C33.0463973,14.7 34.3,15.9536027 34.3,17.5 C34.3,19.0463973 33.0463973,20.3 31.5,20.3 Z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 341 B

After

Width:  |  Height:  |  Size: 720 B

View File

@@ -1,4 +1,4 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M15.9996412,16.8783208 L15.9996412,7.5 C15.9996412,6.67157288 16.671214,6 17.4996412,6 C18.3280683,6 18.9996412,6.67157288 18.9996412,7.5 L18.9996412,16.8790385 L21.4393398,14.4393398 C22.0251263,13.8535534 22.9748737,13.8535534 23.5606602,14.4393398 C24.1464466,15.0251263 24.1464466,15.9748737 23.5606602,16.5606602 L18.5606602,21.5606602 C17.9748737,22.1464466 17.0251263,22.1464466 16.4393398,21.5606602 L11.4393398,16.5606602 C10.8535534,15.9748737 10.8535534,15.0251263 11.4393398,14.4393398 C12.0251263,13.8535534 12.9748737,13.8535534 13.5606602,14.4393398 L15.9996412,16.8783208 Z M10.5,28 C9.67157288,28 9,27.3284271 9,26.5 C9,25.6715729 9.67157288,25 10.5,25 L24.5,25 C25.3284271,25 26,25.6715729 26,26.5 C26,27.3284271 25.3284271,28 24.5,28 L10.5,28 Z"></path>
<path d="M23.9705882,15.6149321 L17.5001879,22.8529412 L11.0294118,15.614659 L12.6140297,14.13906 L16.4261014,18.4006328 L16.4261014,6.38235294 L18.5738986,6.38235294 L18.5738986,18.4284934 L22.3859703,14.1393332 L23.9705882,15.6149321 Z M7.5,28.6176471 L7.5,26.2647059 L27.5,26.2647059 L27.5,28.6176471 L7.5,28.6176471 Z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 942 B

After

Width:  |  Height:  |  Size: 491 B

View File

@@ -1,4 +1,4 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M6.12132034,9 L17.5,20.3786797 L28.8786797,9 L6.12132034,9 Z M31,11.1213203 L18.5606602,23.5606602 C17.9748737,24.1464466 17.0251263,24.1464466 16.4393398,23.5606602 L4,11.1213203 L4,26 L31,26 L31,11.1213203 Z M2.5,6 L32.5,6 C33.3284271,6 34,6.67157288 34,7.5 L34,27.5 C34,28.3284271 33.3284271,29 32.5,29 L2.5,29 C1.67157288,29 1,28.3284271 1,27.5 L1,7.5 C1,6.67157288 1.67157288,6 2.5,6 Z"></path>
<path d="M3.03045763,9 L3,9 L3,26 L32,26 L32,9 L31.9695424,9 L17.5,23.3241161 L3.03045763,9 Z M0,6 L35,6 L35,29 L0,29 L0,6 Z M27.7053105,9 L7.29468951,9 L17.5,19.102742 L27.7053105,9 Z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 569 B

After

Width:  |  Height:  |  Size: 354 B

View File

@@ -1,6 +1,6 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect class="line-top" x="3" y="6" width="29" height="3" rx="1.5"></rect>
<rect class="line-middle" x="3" y="16" width="29" height="3" rx="1.5"></rect>
<rect class="line-bottom" x="3" y="26" width="29" height="3" rx="1.5"></rect>
<rect class="line-top" x="3" y="6" width="29" height="3"></rect>
<rect class="line-middle" x="3" y="16" width="29" height="3"></rect>
<rect class="line-bottom" x="3" y="26" width="29" height="3"></rect>
</svg>

Before

Width:  |  Height:  |  Size: 398 B

After

Width:  |  Height:  |  Size: 371 B

View File

@@ -1,4 +1,4 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M9,30.6571365 L31.5466546,17.5217649 L9,4.38624411 L9,30.6571365 Z M8.06559183,3.82372129 C8.11385613,3.86213396 8.16060259,3.89389381 8.20583948,3.91964378 L8.06559183,3.82372129 Z M8.4983486,31.0038586 C8.46934226,31.0038586 8.4665067,31.0040799 8.49521517,31.0097894 C8.51358323,31.0044274 8.51354824,31.0038586 8.4983486,31.0038586 Z M9.82181934,1.39303795 L33.7559217,15.3368759 L33.9349236,15.4593044 C34.5868249,15.9781407 35,16.6468541 35,17.5216878 C35,18.4257399 34.5132392,19.2516282 33.7559217,19.7064998 L9.82726706,33.6443539 C9.66667195,33.7505899 9.49940323,33.8345151 9.31683935,33.8949975 C9.0236245,33.992138 8.86416284,34.0038586 8.4983486,34.0038586 C8.24745197,34.0038586 8.14898904,33.9995939 7.95603549,33.9612019 C7.73137005,33.9165001 7.55145108,33.8463643 7.32902093,33.7352886 L7.18821849,33.6649755 L7.06507641,33.566969 C6.41317513,33.0481327 6,32.3794194 6,31.5045856 L6,3.53879008 C6,2.63473804 6.4867608,1.80884967 7.22662515,1.3643049 C7.99391167,0.903283625 9.03327302,0.844492269 9.82181934,1.39303795 Z"></path>
<path d="M5.21268739,34.0493335 L5.21268739,0.950666475 L35,17.5 L5.21268739,34.0493335 Z M28.8228577,17.5 L8.21268739,6.04933352 L8.21268739,28.9506665 L28.8228577,17.5 Z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 341 B

View File

@@ -3,5 +3,5 @@
<path d="M15,22 C18.8659932,22 22,18.8659932 22,15 C22,11.1340068 18.8659932,8 15,8 C11.1340068,8 8,11.1340068 8,15 C8,18.8659932 11.1340068,22 15,22 Z M15,25 C9.4771525,25 5,20.5228475 5,15 C5,9.4771525 9.4771525,5 15,5 C20.5228475,5 25,9.4771525 25,15 C25,20.5228475 20.5228475,25 15,25 Z"
class="circle" fill-rule="nonzero"></path>
<rect class="line" transform="translate(25.303301, 25.303301) rotate(45.000000) translate(-25.303301, -25.303301) "
x="19.3033009" y="23.8033009" width="12" height="3" rx="1.5"></rect>
x="19.3033009" y="23.8033009" width="12" height="3"></rect>
</svg>

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 695 B

View File

@@ -1,4 +1,5 @@
<svg width="50px" height="50px" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg"
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M35.3991009,16.5843195 C35.9048173,16.1143809 36.6957419,16.1433845 37.1656805,16.6491009 C37.6356191,17.1548173 37.6066155,17.9457419 37.1008991,18.4156805 L20.9589061,33.4156805 C20.4523976,33.8863552 19.659996,33.8564187 19.1904442,33.348869 L12.8324372,26.4763471 C12.3636198,25.9695911 12.3943751,25.1787327 12.901131,24.7099153 C13.407887,24.2410979 14.1987454,24.2718532 14.6675628,24.7786091 L20.1748187,30.7315338 L35.3991009,16.5843195 Z"></path>
<polygon
points="10.6706826 25.357247 32.4535139 5.11547945 34.6318156 7.45962147 10.4996447 29.8845205 0.3681844 18.9331827 2.71714513 16.7600781"></polygon>
</svg>

Before

Width:  |  Height:  |  Size: 626 B

After

Width:  |  Height:  |  Size: 331 B

View File

@@ -4,14 +4,14 @@
{% block content %}
<div class="content__frame">
{% block content_intro %}
{% include 'project/includes/content_intro.html' %}
{% include 'project/includes/content_intro.html' with image=request.current_page.imageextension.image cropping=request.current_page.imageextension.cropping %}
{% endblock %}
<div class="content__container">
<div class="content__navigation reveal_self reveal reveal_animation data_delay_3">
<div class="content__navigation__frame">
<div class="content__navigation__main">
<span class="content__navigation__title">
{{ request.current_page }}
{% block navigation_title %}{{ request.current_page }}{% endblock %}
</span>
<div class="content__navigation__content">
<div class="content__navigation__progress">

View File

@@ -0,0 +1,14 @@
{% extends 'main.html' %}
{% load i18n %}
{% block content %}
<div class="content__frame content__frame--dialog">
<div class="content__container">
<div class="content__dialog">
{% block dialog %}
{% endblock %}
</div>
</div>
</div>
{% endblock %}

View File

@@ -1,15 +1,17 @@
{% load i18n cms_tags thumbnail %}
<div class="content__intro reveal_container reveal_self reveal reveal_animation{% if request.current_page.imageextension.image %} image{% endif %}">
<h1 class="reveal reveal_animation">
{% if content_title %}
{{ content_title }}
{% else %}
{% page_attribute page_title %}
{% endif %}
</h1>
{% if request.current_page.imageextension.image %}
{% thumbnail request.current_page.imageextension.image 1600x800 box=request.current_page.imageextension.cropping crop detail as thumb %}
<div class="content__intro reveal_container reveal_self reveal reveal_animation{% if image %} image{% endif %}">
<div class="content__intro__content reveal reveal_animation">
<h1>
{% if content_title %}
{{ content_title }}
{% else %}
{% page_attribute page_title %}
{% endif %}
</h1>
</div>
{% if image %}
{% thumbnail image 1600x800 box=cropping crop detail as thumb %}
<div class="content__intro__image scroll reveal reveal_animation" data-ease-multiplier="-2"
style="background-image: url({{ thumb.url }})"></div>
{% endif %}

View File

@@ -0,0 +1,18 @@
<div class="form__field{% if label %} form__field--label{% endif %}">
{% if label %}
<label for="{{ field.id_for_label }}"><span>{{ field.label }}</span></label>
{% endif %}
{{ field }}
{% if field.errors %}
<p class="form__field__errors">
{% for error in field.errors %}
{{ error }}{% if not forloop.last %}<br>{% endif %}
{% endfor %}
</p>
{% endif %}
{% if field.help_text %}
<p class="form__field__help_text">{{ field.help_text }}</p>
{% endif %}
</div>

View File

@@ -4,7 +4,7 @@
{% for n in 'nn' %}
<div class="{% cycle 'navigation__images' 'navigation__list' %}">
{% for child in children|slice:'3' %}
{% thumbnail child.id|page_image 800x1200 crop=True as thumb %}
{% thumbnail child.id|page_image 800x1200 box=child.id|page_image_cropping crop as thumb %}
<div class="navigation__item data_id_{{ forloop.counter0 }}" data-id="{{ forloop.counter0 }}">
{% if forloop.parentloop.first %}
<div class="navigation__item__background"

View File

@@ -17,8 +17,8 @@
<div class="search__results">
<p class="section__text search__results__amount">
{% if page_obj.object_list|length > 0 %}
{% blocktrans with amount=page_obj.object_list|length q=search_form.q.value %}
{% if search_results|length > 0 %}
{% blocktrans with amount=search_results|length q=search_form.q.value %}
{{ amount }} Resultate für «{{ q }}»:
{% endblocktrans %}
{% else %}
@@ -33,11 +33,10 @@
{% endif %}
</p>
<ul>
{% for page in page_obj.object_list %}
{% for page in search_results %}
{% include "project/includes/page_item.html" with search=True image=page.object.page.imageextension.image cropping=page.object.page.imageextension.cropping %}
{% endfor %}
</ul>
{# {% include "project/includes/pagination.html" with obj_string=_('results') %}#}
</div>
</div>
</div>

View File

@@ -6,15 +6,11 @@
<span class="download__item__file__icon">{{ item.extension }}</span>
</span>
<span class="download__item__title">{{ item.label }}</span>
{% if item.description %}
<span class="download__item__description">{{ item.description }}</span>
{% endif %}
<span class="download__item__description">{{ item.description }}</span>
<span class="downloads__item__tags">{{ item.tag_list }}</span>
<span class="download__item__icon">
{% include 'project/assets/download.svg' %}
</span>
{% if item.tag_list %}
<span class="downloads__item__tags">{{ file.tag_list }}</span>
{% endif %}
</a>
</li>
{% endfor %}

View File

@@ -11,3 +11,11 @@ def page_image(id):
return Page.objects.get(pk=id).imageextension.image
except:
return None
@register.filter
def page_image_cropping(id):
try:
return Page.objects.get(pk=id).imageextension.cropping
except:
return None

View File

@@ -8,6 +8,7 @@ from project.forms import NewsletterSubscriptionForm
class SearchView(AldrynSearchView):
template_name = 'project/search.html'
context_object_name = 'search_results'
def get_context_data(self, **kwargs):
context = super(SearchView, self).get_context_data(**kwargs)