1 Commits

Author SHA1 Message Date
90d7eea59e init crazy experiment 2022-10-04 16:16:25 +00:00
7 changed files with 792 additions and 81 deletions

View File

@@ -167,3 +167,31 @@ class PostSearchForm(forms.Form):
self.fields["year"].choices = year_choices
except:
pass
class PostUpdateForm(forms.ModelForm):
class Meta:
model = Post
fields = [
"title",
"image",
"body",
"is_pinned",
"status",
]
labels = {
"title": "Titel",
"image": "Hintergrundbild",
"body": "Text",
"is_pinned": "Event anheften",
}
widgets = {"body": CKEditorUploadingWidget(config_name="default")}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # to get the self.fields set

View File

@@ -138,7 +138,7 @@ class Post(models.Model):
)
def get_absolute_url(self):
return reverse("posts:show", kwargs={"id": self.slug})
return reverse("posts:show", kwargs={"slug": self.slug})
def save(self, *args, **kwargs):
# save the post with some defaults

View File

@@ -10,7 +10,8 @@ urlpatterns = [
path("", views.index, name="index"),
# fet calendar (path have to be ahead show)
path("fet_calendar.ics", views.calendar, name="calendar"),
path("<str:id>", views.show, name="show"),
path("<slug:slug>", views.PostDetailView.as_view(), name="show"),
path("<slug:slug>/update", views.PostUpdateView.as_view(), name="post-update"),
re_path(
r"^(?P<id>[-\w]+)/agenda.pdf$",
views.show_pdf_agenda,

View File

@@ -1,15 +1,19 @@
import logging
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse, Http404
from django.shortcuts import render
from django.template.loader import render_to_string
from django.utils import timezone
from django.views.generic.edit import UpdateView
from django.views.generic.detail import DetailView
from authentications.decorators import authenticated_user
from documents.etherpadlib import add_ep_cookie
from fet2020.utils import add_log_action
from members.models import Member
from .forms import PostSearchForm
from .forms import PostSearchForm, PostUpdateForm
from .models import Event, FileUpload, Post
from .utils import render_to_pdf
@@ -103,41 +107,84 @@ def __get_post_object(id=None, public=True):
return post
def show(request, id=None):
public_only = not request.user.is_authenticated
post = __get_post_object(id, public_only)
def post_next(post=None, public=True):
"""
Helper function for getting next post
"""
posts = None
d = post.slug
# files
files = FileUpload.objects.filter(post=post)
if post:
posts = Post.objects.date_sorted_list(public).filter(post_type=post.post_type)
# author
author = None
author_image = None
post_author = Member.all_members.filter(username=post.author).first()
if post_author:
author = post_author
author_image = post_author.image["avatar"].url
if posts:
for k, v in enumerate(posts):
if post.slug == v.slug:
if (k + 1) < len(posts):
d = posts[k + 1].slug
else:
d = posts[0].slug
break
related_posts = post.tags.similar_objects()
# list of non 'is_hidden' posts for related_posts
for obj in related_posts:
if not obj.published:
related_posts.remove(obj)
return d
context = {
"post": post,
"files": files,
"author": author,
"author_image": author_image,
"next": __next(post, public_only),
"previous": __previous(post, public_only),
"related_posts": related_posts[:4],
}
response = render(request, "posts/show.html", context)
def post_previous(post=None, public=True):
"""
Helper function for getting previous post
"""
posts = None
d = post.slug
if post:
posts = Post.objects.date_sorted_list(public).filter(post_type=post.post_type)
if posts:
for k, v in enumerate(posts):
if post.slug == v.slug:
if k < 1:
d = posts[len(posts) - 1].slug
else:
d = posts[k - 1].slug
break
return d
class PostUpdateView(LoginRequiredMixin, UpdateView):
model = Post
def form_valid(self, form):
add_log_action(self.request, form, "posts", "post", False)
return super().form_valid(form)
def get_form_class(self):
form_class = PostUpdateForm
if self.object.post_type == "E":
form_class = PostUpdateForm
elif self.object.post_type == "F":
form_class = PostUpdateForm
return form_class
def get_template_names(self):
template_name = "posts/news_update.html"
if self.object.post_type == "E":
template_name = "posts/news_update.html"
elif self.object.post_type == "F":
template_name = "posts/news_update.html"
return template_name
class PostDetailView(DetailView):
model = Post
def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs)
# check if etherpad server works
if post.agenda_link or post.protocol_link:
if self.post.agenda_link or self.post.protocol_link:
try:
response = add_ep_cookie(request, response)
except Exception as e:
@@ -145,6 +192,54 @@ def show(request, id=None):
return response
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
public_only = not self.request.user.is_authenticated
self.post = self.object
# files
files = FileUpload.objects.filter(post=self.post)
# author
author = None
author_image = None
post_author = Member.all_members.filter(username=self.post.author).first()
if post_author:
author = post_author
author_image = post_author.image["avatar"].url
related_posts = self.post.tags.similar_objects()
# list of non 'is_hidden' posts for related_posts
for obj in related_posts:
if not obj.published:
related_posts.remove(obj)
context = {
"post": self.post,
"files": files,
"author": author,
"author_image": author_image,
"next": post_next(self.post, public_only),
"previous": post_previous(self.post, public_only),
"related_posts": related_posts[:4],
}
return context
def get_queryset(self):
public_only = not self.request.user.is_authenticated
return Post.objects.published(public_only)
def get_template_names(self):
template_name = "posts/show.html"
if self.post.post_type == "E":
template_name = "posts/event_detail.html"
elif self.post.post_type == "F":
template_name = "posts/fet_meeting_detail.html"
return template_name
def show_pdf(request, html, filename):
rendered = render_to_string(
@@ -185,47 +280,3 @@ def show_pdf_protocol(request, id):
html = post.protocol_html
return show_pdf(request, html, post.slug + "-protokoll")
def __next(post=None, public=True):
"""
Helper function for getting next post
"""
posts = None
d = post.slug
if post:
posts = Post.objects.date_sorted_list(public).filter(post_type=post.post_type)
if posts:
for k, v in enumerate(posts):
if post.slug == v.slug:
if (k + 1) < len(posts):
d = posts[k + 1].slug
else:
d = posts[0].slug
break
return d
def __previous(post=None, public=True):
"""
Helper function for getting previous post
"""
posts = None
d = post.slug
if post:
posts = Post.objects.date_sorted_list(public).filter(post_type=post.post_type)
if posts:
for k, v in enumerate(posts):
if post.slug == v.slug:
if k < 1:
d = posts[len(posts) - 1].slug
else:
d = posts[k - 1].slug
break
return d

View File

@@ -0,0 +1,229 @@
{% extends 'base.html' %}
{% load flatpages %}
{% load post_helpers %}
{% block title %}{{ post.title }}{% endblock %}
{% block extraheader %}
<meta content="{{ post.imageurl }}" property="og:image">
<meta content="{{ post.title }}" property="og:title">
<meta content="article" property="og:type">
<meta content="" property="og:url">
{% endblock %}
{% block content %}
<!-- Main Content -->
<main class="container mx-auto w-full flex-1 my-8 sm:flex flex-col sm:px-4">
<a href="{% url 'posts:show' previous %}" class="hidden z-20 fixed left-0 top-1/2 -mt-8 p-2 xl:flex items-center text-gray-400 dark:text-gray-300 rounded-md"
x-data="{ showPrevArticleButton : false }"
@mouseleave="showPrevArticleButton = false"
@mouseover="showPrevArticleButton = true"
>
<i class="fa-solid fa-chevron-left text-5xl -m-2 p-2 bg-gray-100 dark:bg-gray-700 rounded-md"></i>
<span class="text-gray-600 dark:text-gray-300 font-medium bg-gray-100 dark:bg-gray-700 -m-2 p-2 rounded-r-md origin-left"
x-show="showPrevArticleButton"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 bg-opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 bg-opacity-0 transform scale-100"
>Vorheriges<br>Event</span>
</a>
<a href="{% url 'posts:show' next %}" class="hidden z-20 fixed right-0 top-1/2 -mt-8 p-2 xl:flex items-center text-gray-400 dark:text-gray-300 rounded-md"
x-data="{ showNextArticleButton : false }"
@mouseleave="showNextArticleButton = false"
@mouseover="showNextArticleButton = true"
>
<span class="z-30 text-gray-600 dark:text-gray-300 font-medium bg-gray-100 dark:bg-gray-700 -m-2 p-2 rounded-l-md text-right origin-right"
x-show="showNextArticleButton"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 bg-opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 bg-opacity-0 transform scale-100"
>Nächstes<br>Event</span>
<i class="fa-solid fa-chevron-right text-5xl -m-2 p-2 bg-gray-100 dark:bg-gray-700 rounded-md"></i>
</a>
<section>
<div class="mb-4 flex flex-col sm:flex-col gap-2 mx-auto">
<ul class="px-4 sm:px-0 mb-2 flex flex-row justify-center gap-2 sm:gap-4 flex-wrap text-sky-700 dark:text-blue-200 text-sm uppercase tracking-wide sm:font-medium">
{% for t in post.tag_names %}
<li class="inline-block py-1 px-2 bg-sky-100 dark:bg-sky-900 rounded-full"><a href="{% url 'posts:tags' t %}">#{{ t }}</a></li>
{% endfor %}
</ul>
<h1 class="px-4 sm:px-0 text-lg sm:text-xl lg:text-3xl text-center sm:text-left font-medium text-gray-900 dark:text-gray-100 font-serif tracking-wider leading-normal" style="line-height: 1.5;">{{ post.title|tags_to_url }}</h1>
<div class="mx-auto max-w-max sm:mx-0 sm:max-w-none sm:flex justify-between items-center">
<div class="max-w-max flex flex-row justify-center sm:justify-start gap-2 self-center md:self-start">
{% if author_image and author %}
<img class="hidden sm:block w-12 rounded-full" src="{{ author_image }}" alt="Portraitfoto von {{ author.firstname }}">
<div class="sm:flex flex-col justify-evenly text-gray-600 dark:text-gray-300 text-sm sm:text-base">
<a href="{% url 'member' author.id %}" class="underline">{{ author.firstname }}</a>
<span class="sm:hidden"> am </span>
<span>{{ post.date|date:"d. F Y" }}</span>
</div>
{% elif post.author %}
<div class="sm:flex flex-col justify-evenly text-gray-600 dark:text-gray-300 text-sm sm:text-base">
<a class="underline">{{ post.author|capfirst }}</a>
<span class="sm:hidden"> am </span>
<span>{{ post.date|date:"d. F Y" }}</span>
</div>
{% else %}
<div class="sm:flex flex-col justify-evenly text-gray-600 dark:text-gray-300 text-sm sm:text-base">
<a class="underline">fet.at Redaktion</a>
<span class="sm:hidden"> am </span>
<span>{{ post.date|date:"d. F Y" }}</span>
</div>
{% endif %}
</div>
{% if request.user.is_authenticated %}
<a href="{% url 'admin:posts_event_change' post.id %}" class="hidden sm:block btn-small btn-primary">
<i class="fa-solid fa-pen-to-square mr-1"></i>Event bearbeiten
</a>
{% endif %}
</div>
</div>
<!-- <img src="img/article-cover-3.jpg" alt="" class="h-44 sm:h-56 lg:h-64 xl:h-80 w-full object-cover sm:rounded-md max-w-5xl mx-auto"> -->
<div class="relative w-full h-44 sm:h-56 md:h-60 lg:h-64 xl:h-96 bg-center bg-no-repeat bg-cover sm:rounded-md mx-auto" style="background-image: url('{{ post.imageurl }}');">
<div class="hidden lg:block absolute top-0 right-0 bg-white dark:bg-gray-900 rounded-bl p-2 bg-opacity-80 dark:bg-opacity-70 gap-2">
<div class="items-center lg:flex gap-2">
<i class="flex-none fa-solid fa-calendar-clock fa-fw text-gray-800 dark:text-gray-200"></i>
<span class="flex-1 text-sm text-gray-800 dark:text-gray-200">
Event-Start: {{ post.event_start|date }} um {{ post.event_start|time }} Uhr<br>
Event-Ende: {{ post.event_end|date }} um {{ post.event_end|time }} Uhr
</span>
</div>
{% if post.event_place %}
<div class="items-center lg:flex gap-2">
<i class="flex-none fa-solid fa-location-dot fa-fw text-gray-800 dark:text-gray-200"></i>
<span class="flex-1 text-sm text-gray-800 dark:text-gray-200">
Event-Ort: {{ post.event_place }}
</span>
</div>
{% endif %}
</div>
<div class="hidden absolute top-0 right-0 bg-white dark:bg-gray-900 rounded-bl p-2 bg-opacity-80 dark:bg-opacity-70 items-center gap-2">
<i class="flex-none fa-solid fa-calendar-clock text-gray-800 dark:text-gray-200"></i>
<span class="flex-1 text-sm text-gray-800 dark:text-gray-200">
Event-Start: {{ post.event_start|date }} um {{ post.event_start|time }} Uhr<br>
Event-Ende: {{ post.event_end|date }} um {{ post.event_end|time }} Uhr<br>
{% if post.event_place %}
Event-Ort: {{ post.event_place }}
{% endif %}
</span>
</div>
</div>
</section>
<section class="mx-4 z-10">
<article class="p-4 mt-4 sm:-mt-16 xl:-mt-24 w-full max-w-prose mx-auto bg-white dark:bg-gray-900 rounded dark:border-2 dark:border-gray-800">
<!-- <div class="w-full flex justify-end">
<div class="hidden lg:block max-w-max text-sm text-gray-600">
Event-Start: 23. August 2021 um 18:00 Uhr<br>
Event-Ende: 23. August 2021 um 20:00 Uhr
</div>
</div> -->
<div class="db-page-content-left big-first-letter">
<!-- Content from DB here: -->
{{ post.body|safe|tags_to_url }}
</div>
<hr class="lg:hidden -mx-4 border-gray-200 dark:border-gray-800 dark:border my-4">
<div class="lg:hidden">
<h2 class="text-gray-800 dark:text-gray-200 font-medium"><i class="fa-solid fa-calendar-days mr-2 text-gray-400 dark:text-gray-500"></i>Termindetails:</h2>
<ul class="text-base text-gray-700 dark:text-gray-300 my-1">
<li>Start: {{ post.event_start|date }} um {{ post.event_start|time }} Uhr</li>
<li>Ende: {{ post.event_end|date }} um {{ post.event_end|time }} Uhr</li>
{% if post.event_place %}
<li>Ort: {{ post.event_place }}</li>
{% endif %}
</ul>
</div>
{% if files %}
<hr class="-mx-4 border-gray-200 dark:border-gray-800 dark:border my-4">
<h2 class="text-gray-800 dark:text-gray-200 font-medium"><i class="fa-solid fa-inbox mr-2 text-gray-400 dark:text-gray-500"></i>Dokument(e):</h2>
{% endif %}
{% for file in files %}
<div class="w-full my-2 flex items-center gap-4 text-gray-700 dark:text-gray-300" x-data="{ showOptions: false }">
<span class="flex-1">{{ file.title }}</span>
<div class="relative">
<button class="sm:hidden px-2 py-1 border border-gray-300 dark:border-gray-700 rounded" @click="showOptions = true">
<i class="fa-solid fa-ellipsis-vertical fa-fw"></i>
</button>
<ul class="z-10 absolute top-0 right-0 sm:flex flex-row sm:static flex-none border dark:border-2 border-gray-300 dark:border-gray-700 rounded divide-y-2 sm:divide-y-0 sm:divide-x divide-gray-300 dark:divide-gray-700 bg-gray-100 dark:bg-gray-800 shadow sm:bg-transparent sm:shadow-none"
@click.outside="showOptions = false"
x-show="showOptions || $screen('sm')"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="transform origin-right opacity-0 scale-95"
x-transition:enter-end="transform origin-right opacity-100 scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="transform origin-right opacity-100 scale-100"
x-transition:leave-end="transform origin-right opacity-0 scale-95"
>
<li class="block sm:inline-block group hover:bg-gray-200 dark:hover:bg-gray-800 hover:text-gray-800 dark:hover:text-gray-200">
<a href="{{ file.file_field.url }}" class="inline-flex items-center px-2 py-1" target="_blank">
<i class="fa-solid fa-file-pdf fa-fw text-red-800 dark:text-red-500 md:text-inherit group-hover:text-red-800 dark:group-hover:text-red-500"></i>
<span class="ml-2 sm:ml-1">Download</span>
</a>
</li>
</ul>
</div>
</div>
{% endfor %}
<hr class="-mx-4 border-gray-200 dark:border-gray-800 dark:border my-4">
<div class="-m-4 flex divide-x divide-gray-200 dark:divide-gray-800 dark:divide-x-2 text-sm sm:text-base">
<a href="{% url 'posts:show' previous %}" class="w-1/2 p-4 flex items-center gap-2">
<i class="fa-solid fa-chevron-left text-gray-600 dark:text-gray-400"></i>
<span class="text-gray-700 dark:text-gray-300 font-medium">Vorheriges Event</span>
</a>
<a href="{% url 'posts:show' next %}" class="w-1/2 p-4 flex flex-row-reverse items-center gap-2">
<i class="fa-solid fa-chevron-right text-gray-600 dark:text-gray-400"></i>
<span class="text-gray-700 dark:text-gray-300 font-medium">Nächstes Event</span>
</a>
</div>
</article>
{% if request.user.is_authenticated %}
<a href="{% url 'admin:posts_event_change' post.id %}" class="sm:hidden block w-full btn btn-primary mt-4">
<i class="fa-solid fa-pen-to-square mr-1"></i>Event bearbeiten
</a>
{% endif %}
</section>
{% if related_posts %}
<section class="mx-auto w-full px-4">
<h2 class="my-4 sm:my-8 text-proprietary dark:text-proprietary-lighter text-xl text-center uppercase tracking-wider">Weiterlesen</h2>
<div class="flex justify-evenly flex-wrap gap-4">
{% for post in related_posts %}
{% if forloop.counter0 == 2 %}
<a href="{{ post.get_absolute_url }}" class="w-full sm:w-auto sm:flex-1 hidden lg:block rounded-md bg-white dark:bg-gray-500 shadow-md bg-no-repeat bg-center aspect-video transition-all ease-in-out duration-500 bg-scale-100 hover:bg-scale-120" style="background-image: url('{{ post.imageurl }}');">
{% include 'posts/partials/_posts_related.html' %}
</a>
{% elif forloop.last %}
<a href="{{ post.get_absolute_url }}" class="w-full sm:w-auto sm:flex-1 hidden 2xl:block rounded-md bg-white dark:bg-gray-500 shadow-md bg-no-repeat bg-center aspect-video transition-all ease-in-out duration-500 bg-scale-100 hover:bg-scale-120" style="background-image: url('{{ post.imageurl }}');">
{% include 'posts/partials/_posts_related.html' %}
</a>
{% else %}
<a href="{{ post.get_absolute_url }}" class="w-full sm:w-auto sm:flex-1 block rounded-md bg-white dark:bg-gray-500 shadow-md bg-no-repeat bg-center aspect-video transition-all ease-in-out duration-500 bg-scale-100 hover:bg-scale-120" style="background-image: url('{{ post.imageurl }}');">
{% include 'posts/partials/_posts_related.html' %}
</a>
{% endif %}
{% endfor %}
</div>
</section>
{% endif %}
</main>
{% endblock %}

View File

@@ -0,0 +1,315 @@
{% extends 'base.html' %}
{% load flatpages %}
{% load post_helpers %}
{% block title %}{{ post.title }}{% endblock %}
{% block extraheader %}
<meta content="{{ post.imageurl }}" property="og:image">
<meta content="{{ post.title }}" property="og:title">
<meta content="article" property="og:type">
<meta content="" property="og:url">
{% endblock %}
{% block content %}
<!-- Main Content -->
<main class="container mx-auto w-full flex-1 my-8 sm:flex flex-col sm:px-4">
<a href="{% url 'posts:show' previous %}" class="hidden z-20 fixed left-0 top-1/2 -mt-8 p-2 xl:flex items-center text-gray-400 dark:text-gray-300 rounded-md"
x-data="{ showPrevArticleButton : false }"
@mouseleave="showPrevArticleButton = false"
@mouseover="showPrevArticleButton = true"
>
<i class="fa-solid fa-chevron-left text-5xl -m-2 p-2 bg-gray-100 dark:bg-gray-700 rounded-md"></i>
<span class="text-gray-600 dark:text-gray-300 font-medium bg-gray-100 dark:bg-gray-700 -m-2 p-2 rounded-r-md origin-left"
x-show="showPrevArticleButton"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 bg-opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 bg-opacity-0 transform scale-100"
>Vorherige<br>Fachschaftssitzung</span>
</a>
<a href="{% url 'posts:show' next %}" class="hidden z-20 fixed right-0 top-1/2 -mt-8 p-2 xl:flex items-center text-gray-400 dark:text-gray-300 rounded-md"
x-data="{ showNextArticleButton : false }"
@mouseleave="showNextArticleButton = false"
@mouseover="showNextArticleButton = true"
>
<span class="z-30 text-gray-600 dark:text-gray-300 font-medium bg-gray-100 dark:bg-gray-700 -m-2 p-2 rounded-l-md text-right origin-right"
x-show="showNextArticleButton"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 bg-opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 bg-opacity-0 transform scale-100"
>Nächste<br>Fachschaftssitzung</span>
<i class="fa-solid fa-chevron-right text-5xl -m-2 p-2 bg-gray-100 dark:bg-gray-700 rounded-md"></i>
</a>
<section>
<div class="mb-4 flex flex-col sm:flex-col gap-2 mx-auto">
<ul class="px-4 sm:px-0 mb-2 flex flex-row justify-center gap-2 sm:gap-4 flex-wrap text-sky-700 dark:text-blue-200 text-sm uppercase tracking-wide sm:font-medium">
{% for t in post.tag_names %}
<li class="inline-block py-1 px-2 bg-sky-100 dark:bg-sky-900 rounded-full"><a href="{% url 'posts:tags' t %}">#{{ t }}</a></li>
{% endfor %}
</ul>
<h1 class="px-4 sm:px-0 text-lg sm:text-xl lg:text-3xl text-center sm:text-left font-medium text-gray-900 dark:text-gray-100 font-serif tracking-wider leading-normal" style="line-height: 1.5;">{{ post.title|tags_to_url }}</h1>
<div class="mx-auto max-w-max sm:mx-0 sm:max-w-none sm:flex justify-between items-center">
<div class="max-w-max flex flex-row justify-center sm:justify-start gap-2 self-center md:self-start">
{% if author_image and author %}
<img class="hidden sm:block w-12 rounded-full" src="{{ author_image }}" alt="Portraitfoto von {{ author.firstname }}">
<div class="sm:flex flex-col justify-evenly text-gray-600 dark:text-gray-300 text-sm sm:text-base">
<a href="{% url 'member' author.id %}" class="underline">{{ author.firstname }}</a>
<span class="sm:hidden"> am </span>
<span>{{ post.date|date:"d. F Y" }}</span>
</div>
{% elif post.author %}
<div class="sm:flex flex-col justify-evenly text-gray-600 dark:text-gray-300 text-sm sm:text-base">
<a class="underline">{{ post.author|capfirst }}</a>
<span class="sm:hidden"> am </span>
<span>{{ post.date|date:"d. F Y" }}</span>
</div>
{% else %}
<div class="sm:flex flex-col justify-evenly text-gray-600 dark:text-gray-300 text-sm sm:text-base">
<a class="underline">fet.at Redaktion</a>
<span class="sm:hidden"> am </span>
<span>{{ post.date|date:"d. F Y" }}</span>
</div>
{% endif %}
</div>
{% if request.user.is_authenticated %}
<a href="{% url 'admin:posts_fetmeeting_change' post.id %}" class="hidden sm:block btn-small btn-primary">
<i class="fa-solid fa-pen-to-square mr-1"></i>Fachschaftssitzung bearbeiten
</a>
{% endif %}
</div>
</div>
<!-- <img src="img/article-cover-3.jpg" alt="" class="h-44 sm:h-56 lg:h-64 xl:h-80 w-full object-cover sm:rounded-md max-w-5xl mx-auto"> -->
<div class="relative w-full h-44 sm:h-56 md:h-60 lg:h-64 xl:h-96 bg-center bg-no-repeat bg-cover sm:rounded-md mx-auto" style="background-image: url('{{ post.imageurl }}');">
<div class="hidden lg:block absolute top-0 right-0 bg-white dark:bg-gray-900 rounded-bl p-2 bg-opacity-80 dark:bg-opacity-70 gap-2">
<div class="items-center lg:flex gap-2">
<i class="flex-none fa-solid fa-calendar-clock fa-fw text-gray-800 dark:text-gray-200"></i>
<span class="flex-1 text-sm text-gray-800 dark:text-gray-200">
Event-Start: {{ post.event_start|date }} um {{ post.event_start|time }} Uhr<br>
Event-Ende: {{ post.event_end|date }} um {{ post.event_end|time }} Uhr
</span>
</div>
{% if post.event_place %}
<div class="items-center lg:flex gap-2">
<i class="flex-none fa-solid fa-location-dot fa-fw text-gray-800 dark:text-gray-200"></i>
<span class="flex-1 text-sm text-gray-800 dark:text-gray-200">
Event-Ort: {{ post.event_place }}
</span>
</div>
{% endif %}
</div>
<div class="hidden absolute top-0 right-0 bg-white dark:bg-gray-900 rounded-bl p-2 bg-opacity-80 dark:bg-opacity-70 items-center gap-2">
<i class="flex-none fa-solid fa-calendar-clock text-gray-800 dark:text-gray-200"></i>
<span class="flex-1 text-sm text-gray-800 dark:text-gray-200">
Event-Start: {{ post.event_start|date }} um {{ post.event_start|time }} Uhr<br>
Event-Ende: {{ post.event_end|date }} um {{ post.event_end|time }} Uhr<br>
{% if post.event_place %}
Event-Ort: {{ post.event_place }}
{% endif %}
</span>
</div>
</div>
</section>
<section class="mx-4 z-10">
<article class="p-4 mt-4 sm:-mt-16 xl:-mt-24 w-full max-w-prose mx-auto bg-white dark:bg-gray-900 rounded dark:border-2 dark:border-gray-800">
<!-- <div class="w-full flex justify-end">
<div class="hidden lg:block max-w-max text-sm text-gray-600">
Event-Start: 23. August 2021 um 18:00 Uhr<br>
Event-Ende: 23. August 2021 um 20:00 Uhr
</div>
</div> -->
<div class="db-page-content-left big-first-letter">
<!-- Content from DB here: -->
{% if post.has_agenda %}
<h2>Agenda</h2>
{{ post.agenda_html|safe }}
{% endif %}
{% if request.user.is_authenticated and post.has_protocol %}
<hr>
<h2>Protokoll</h2>
{{ post.protocol_html|safe }}
{% endif %}
</div>
<hr class="lg:hidden -mx-4 border-gray-200 dark:border-gray-800 dark:border my-4">
<div class="lg:hidden">
<h2 class="text-gray-800 dark:text-gray-200 font-medium"><i class="fa-solid fa-calendar-days mr-2 text-gray-400 dark:text-gray-500"></i>Termindetails:</h2>
<ul class="text-base text-gray-700 dark:text-gray-300 my-1">
<li>Start: {{ post.event_start|date }} um {{ post.event_start|time }} Uhr</li>
<li>Ende: {{ post.event_end|date }} um {{ post.event_end|time }} Uhr</li>
{% if post.event_place %}
<li>Ort: {{ post.event_place }}</li>
{% endif %}
</ul>
</div>
{% if post.has_agenda or post.has_protocol %}
{% if request.user.is_authenticated %}
<hr class="-mx-4 border-gray-200 dark:border-gray-800 dark:border my-4">
<h2 class="text-gray-800 dark:text-gray-200 font-medium"><i class="fa-solid fa-inbox mr-2 text-gray-400 dark:text-gray-500"></i>Dokument(e):</h2>
{% endif %}
{% endif %}
{% if request.user.is_authenticated %}
{% if post.has_agenda %}
<div class="w-full my-2 flex items-center gap-4 text-gray-700 dark:text-gray-300" x-data="{ showOptions: false }">
<span class="flex-1">Agenda</span>
<div class="relative">
<button class="sm:hidden px-2 py-1 border border-gray-300 dark:border-gray-700 rounded" @click="showOptions = true">
<i class="fa-solid fa-ellipsis-vertical fa-fw"></i>
</button>
<ul class="z-10 absolute top-0 right-0 sm:flex flex-row sm:static flex-none border dark:border-2 border-gray-300 dark:border-gray-700 rounded divide-y-2 sm:divide-y-0 sm:divide-x divide-gray-300 dark:divide-gray-700 bg-gray-100 dark:bg-gray-800 shadow sm:bg-transparent sm:shadow-none"
@click.outside="showOptions = false"
x-show="showOptions || $screen('sm')"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="transform origin-right opacity-0 scale-95"
x-transition:enter-end="transform origin-right opacity-100 scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="transform origin-right opacity-100 scale-100"
x-transition:leave-end="transform origin-right opacity-0 scale-95"
>
<li class="block sm:inline-block group hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-gray-800 dark:hover:text-gray-200">
<a href="{{ post.agenda_link }}" class="inline-flex items-center px-2 py-1">
<i class="fa-solid fa-file-signature fa-fw text-proprietary dark:text-proprietary-light md:text-inherit group-hover:text-proprietary dark:group-hover:text-proprietary-light"></i>
<span class="ml-2 sm:ml-1">Bearbeiten</span>
</a>
</li>
{% if post.filename_agenda %}
<li class="block sm:inline-block group hover:bg-gray-200 dark:hover:bg-gray-800 hover:text-gray-800 dark:hover:text-gray-200">
<a href="{% url 'posts:show_pdf_agenda' post.slug %}" class="inline-flex items-center px-2 py-1">
<i class="fa-solid fa-file-pdf fa-fw text-red-800 dark:text-red-500 md:text-inherit group-hover:text-red-800 dark:group-hover:text-red-500"></i>
<span class="ml-2 sm:ml-1">Download</span>
</a>
</li>
{% endif %}
</ul>
</div>
</div>
{% endif %}
{% if post.has_protocol %}
<div class="w-full my-2 flex items-center gap-4 text-gray-700 dark:text-gray-300" x-data="{ showOptions: false }">
<span class="flex-1">Protokoll</span>
<div class="relative">
<button class="sm:hidden px-2 py-1 border border-gray-300 dark:border-gray-700 rounded" @click="showOptions = true">
<i class="fa-solid fa-ellipsis-vertical fa-fw"></i>
</button>
<ul class="z-10 absolute top-0 right-0 sm:flex flex-row sm:static flex-none border dark:border-2 border-gray-300 dark:border-gray-700 rounded divide-y-2 sm:divide-y-0 sm:divide-x divide-gray-300 dark:divide-gray-700 bg-gray-100 dark:bg-gray-800 shadow sm:bg-transparent sm:shadow-none"
@click.outside="showOptions = false"
x-show="showOptions || $screen('sm')"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="transform origin-right opacity-0 scale-95"
x-transition:enter-end="transform origin-right opacity-100 scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="transform origin-right opacity-100 scale-100"
x-transition:leave-end="transform origin-right opacity-0 scale-95"
>
<li class="block sm:inline-block group hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-gray-800 dark:hover:text-gray-200">
<a href="{{ post.protocol_link }}" class="inline-flex items-center px-2 py-1"><i class="fa-solid fa-file-signature fa-fw text-proprietary dark:text-proprietary-light md:text-inherit group-hover:text-proprietary dark:group-hover:text-proprietary-light"></i>
<span class="ml-2 sm:ml-1">Bearbeiten</span>
</a>
</li>
{% if post.filename_protocol %}
<li class="block sm:inline-block group hover:bg-gray-200 dark:hover:bg-gray-800 hover:text-gray-800 dark:hover:text-gray-200">
<a href="{% url 'posts:show_pdf_protocol' post.slug %}" class="inline-flex items-center px-2 py-1">
<i class="fa-solid fa-file-pdf fa-fw text-red-800 dark:text-red-500 md:text-inherit group-hover:text-red-800 dark:group-hover:text-red-500"></i>
<span class="ml-2 sm:ml-1">Download</span>
</a>
</li>
{% endif %}
</ul>
</div>
</div>
{% endif %}
{% get_flatpages '/bs/' for user as pages %}
{% if pages %}
<div class="w-full my-2 flex items-center gap-4 text-gray-700 dark:text-gray-300" x-data="{ showOptions: false }">
<span class="flex-1">{{ pages.first.title }}</span>
<div class="relative">
<button class="sm:hidden px-2 py-1 border border-gray-300 dark:border-gray-700 rounded" @click="showOptions = true">
<i class="fa-solid fa-ellipsis-vertical fa-fw"></i>
</button>
<ul class="z-10 absolute top-0 right-0 sm:flex flex-row sm:static flex-none border dark:border-2 border-gray-300 dark:border-gray-700 rounded divide-y-2 sm:divide-y-0 sm:divide-x divide-gray-300 dark:divide-gray-700 bg-gray-100 dark:bg-gray-800 shadow sm:bg-transparent sm:shadow-none"
@click.outside="showOptions = false"
x-show="showOptions || $screen('sm')"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="transform origin-right opacity-0 scale-95"
x-transition:enter-end="transform origin-right opacity-100 scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="transform origin-right opacity-100 scale-100"
x-transition:leave-end="transform origin-right opacity-0 scale-95"
>
<li class="block sm:inline-block group hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-gray-800 dark:hover:text-gray-200">
<a href="{{ pages.first.url }}" class="inline-flex items-center px-2 py-1"><i class="fa-solid fa-file-lines fa-fw text-proprietary dark:text-proprietary-light md:text-inherit group-hover:text-proprietary dark:group-hover:text-proprietary-light"></i>
<span class="ml-2 sm:ml-1">Übersicht</span>
</a>
</li>
</ul>
</div>
</div>
{% endif %}
{% endif %}
<hr class="-mx-4 border-gray-200 dark:border-gray-800 dark:border my-4">
<div class="-m-4 flex divide-x divide-gray-200 dark:divide-gray-800 dark:divide-x-2 text-sm sm:text-base">
<a href="{% url 'posts:show' previous %}" class="w-1/2 p-4 flex items-center gap-2">
<i class="fa-solid fa-chevron-left text-gray-600 dark:text-gray-400"></i>
<span class="text-gray-700 dark:text-gray-300 font-medium">Vorherige Fachschaftssitzung</span>
</a>
<a href="{% url 'posts:show' next %}" class="w-1/2 p-4 flex flex-row-reverse items-center gap-2">
<i class="fa-solid fa-chevron-right text-gray-600 dark:text-gray-400"></i>
<span class="text-gray-700 dark:text-gray-300 font-medium">Nächste Fachschaftssitzung</span>
</a>
</div>
</article>
{% if request.user.is_authenticated %}
<a href="{% url 'admin:posts_fetmeeting_change' post.id %}" class="sm:hidden block w-full btn btn-primary mt-4">
<i class="fa-solid fa-pen-to-square mr-1"></i>Fachschaftssitzung bearbeiten
</a>
{% endif %}
</section>
{% if related_posts %}
<section class="mx-auto w-full px-4">
<h2 class="my-4 sm:my-8 text-proprietary dark:text-proprietary-lighter text-xl text-center uppercase tracking-wider">Weiterlesen</h2>
<div class="flex justify-evenly flex-wrap gap-4">
{% for post in related_posts %}
{% if forloop.counter0 == 2 %}
<a href="{{ post.get_absolute_url }}" class="w-full sm:w-auto sm:flex-1 hidden lg:block rounded-md bg-white dark:bg-gray-500 shadow-md bg-no-repeat bg-center aspect-video transition-all ease-in-out duration-500 bg-scale-100 hover:bg-scale-120" style="background-image: url('{{ post.imageurl }}');">
{% include 'posts/partials/_posts_related.html' %}
</a>
{% elif forloop.last %}
<a href="{{ post.get_absolute_url }}" class="w-full sm:w-auto sm:flex-1 hidden 2xl:block rounded-md bg-white dark:bg-gray-500 shadow-md bg-no-repeat bg-center aspect-video transition-all ease-in-out duration-500 bg-scale-100 hover:bg-scale-120" style="background-image: url('{{ post.imageurl }}');">
{% include 'posts/partials/_posts_related.html' %}
</a>
{% else %}
<a href="{{ post.get_absolute_url }}" class="w-full sm:w-auto sm:flex-1 block rounded-md bg-white dark:bg-gray-500 shadow-md bg-no-repeat bg-center aspect-video transition-all ease-in-out duration-500 bg-scale-100 hover:bg-scale-120" style="background-image: url('{{ post.imageurl }}');">
{% include 'posts/partials/_posts_related.html' %}
</a>
{% endif %}
{% endfor %}
</div>
</section>
{% endif %}
</main>
{% endblock %}

View File

@@ -0,0 +1,87 @@
{% extends 'base.html' %}
{% block title %}{{ object.title }} bearbeiten{% endblock %}
{% block content %}
<!-- Main Content -->
<main class="container mx-auto w-full px-4 my-8 flex-1">
<h1 class="page-title">News '{{ object.title }}' bearbeiten</h1>
<div class="w-full h-full flex-1 flex justify-center items-center">
<form action="" method="POST" class="w-full max-w-prose sm:px-28 sm:py-4 grid grid-cols-1 gap-y-3 sm:gap-y-6 text-gray-900">
{% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger">
<i class="alert-icon fa-solid fa-check-circle"></i>
<h2 class="alert-title">Fehler:</h2>
<div class="alert-body">{{ form.non_field_errors }}</div>
</div>
{% endif %}
<label>
<span class="text-gray-700 dark:text-gray-200">{{ form.assigned_to.label }}</span>
{% if form.assigned_to.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.assigned_to.errors }}</div>
</div>
{% endif %}
<select id="id_assigned_to" name="assigned_to" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
{% for elem in form.assigned_to %}
{% if forloop.first %}
<option value="">Alle</option>
{% else %}
{{ elem }}
{% endif %}
{% endfor %}
</select>
</label>
<label>
<span class="text-gray-700 dark:text-gray-200">{{ form.due_date.label }}</span>
{% if form.due_date.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.due_date.errors }}</div>
</div>
{% endif %}
<input type="date" id="id_due_date" name="due_date" value="{{ task.due_date|date:"Y-m-d" }}" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
</label>
<label>
<span class="text-gray-700 dark:text-gray-200">{{ form.completed_date.label }}</span>
{% if form.completed_date.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.completed_date.errors }}</div>
</div>
{% endif %}
<input type="date" id="id_completed_date" name="completed_date" value="{{ task.completed_date|date:"Y-m-d" }}" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
</label>
<label>
<input type="checkbox" id="id_completed" name="completed" value="{{ task.id }}" {% if task.completed %}checked{% endif %} class="rounded border-gray-300 dark:border-none text-proprietary shadow-sm focus:border-blue-300 focus:ring focus:ring-offset-0 focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
<span class="text-gray-700 dark:text-gray-200">{{ form.completed.label }}</span>
{% if form.completed.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.completed.errors }}</div>
</div>
{% endif %}
</label>
<label class="block">
<span class="text-gray-700 dark:text-gray-200">{{ form.note.label }}</span>
{% if form.note.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.note.errors }}</div>
</div>
{% endif %}
{{ form.media }}
{{ form.note }}
</label>
<div class="flex flex-col-reverse sm:flex-row gap-3 justify-end pt-4 sm:pt-0">
<a href="{% url 'admin:posts_news_change' object.id %}" class="block btn btn-secondary-proprietary">News im Admin bearbeiten</a>
<input type="submit" class="block btn btn-primary" value="Bearbeiten">
</div>
</form>
</div>
</main>
{% endblock %}