diff --git a/.worktime b/.worktime index 4b7ff12..3aa4fc0 100644 --- a/.worktime +++ b/.worktime @@ -4,4 +4,5 @@ 15.06.2022 - 1h 30 mins 23.06.2022 - 1h 30 mins 07.07.2022 - 2h 30 mins -15.07.2022 - 3h \ No newline at end of file +15.07.2022 - 3h +24.07.2022 - 3h 30 mins \ No newline at end of file diff --git a/admin_ordering/LICENSE b/admin_ordering/LICENSE new file mode 100644 index 0000000..0a1d349 --- /dev/null +++ b/admin_ordering/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2016, FEINHEIT AG and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of FEINHEIT GmbH nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/admin_ordering/__init__.py b/admin_ordering/__init__.py new file mode 100644 index 0000000..c97e7e3 --- /dev/null +++ b/admin_ordering/__init__.py @@ -0,0 +1,2 @@ +VERSION = (0, 15, 0) +__version__ = ".".join(map(str, VERSION)) diff --git a/admin_ordering/admin.py b/admin_ordering/admin.py new file mode 100644 index 0000000..e327944 --- /dev/null +++ b/admin_ordering/admin.py @@ -0,0 +1,78 @@ +import inspect +import json + +from django import forms +from django.conf import settings +from django.contrib import admin +from django.contrib.admin.helpers import InlineAdminFormSet +from django.contrib.admin.options import BaseModelAdmin, InlineModelAdmin +from django.core import checks +from js_asset import JS + + +__all__ = ("OrderableAdmin",) + + +class OrderableAdmin(BaseModelAdmin): + ordering_field = "ordering" + ordering_field_hide_input = False + extra = 0 + + @property + def media(self): + if not isinstance(self, InlineModelAdmin): + # Editable change list + context = { + "field": self.ordering_field, + "fieldHideInput": self.ordering_field_hide_input, + } + else: + # Find our helper.InlineAdminFormSet so that we may access + # the formset instance and its prefix + frame = inspect.currentframe() + while frame: # pragma: no branch + helper = frame.f_locals.get("self") + if isinstance(helper, InlineAdminFormSet): + break + frame = frame.f_back + del frame + + context = { + "field": self.ordering_field, + "fieldHideInput": self.ordering_field_hide_input, + "prefix": helper.formset.prefix, + "stacked": isinstance(self, admin.StackedInline), + "tabular": isinstance(self, admin.TabularInline), + } + + return super().media + forms.Media( + css={ + "all": [ + "admin_ordering/jquery-ui.min.css", + "admin_ordering/admin_ordering.css", + ] + }, + js=[ + "admin/js/jquery.init.js", + "admin_ordering/jquery-ui.min.js", + JS( + "admin_ordering/admin_ordering.js", + { + "class": "admin-ordering-context", + "data-context": json.dumps(context), + }, + ), + ], + ) + + def check(self, **kwargs): + errors = super().check(**kwargs) + if "admin_ordering" not in settings.INSTALLED_APPS: + errors.append( + checks.Error( + '"admin_ordering" must be in INSTALLED_APPS.', + obj=self.__class__, + id="admin_ordering.E001", + ) + ) + return errors diff --git a/admin_ordering/locale/de/LC_MESSAGES/django.mo b/admin_ordering/locale/de/LC_MESSAGES/django.mo new file mode 100644 index 0000000..4b2f85d Binary files /dev/null and b/admin_ordering/locale/de/LC_MESSAGES/django.mo differ diff --git a/admin_ordering/locale/de/LC_MESSAGES/django.po b/admin_ordering/locale/de/LC_MESSAGES/django.po new file mode 100644 index 0000000..6043dcc --- /dev/null +++ b/admin_ordering/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,23 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-10-04 20:17+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: models.py:7 +msgid "ordering" +msgstr "Sortierung" diff --git a/admin_ordering/models.py b/admin_ordering/models.py new file mode 100644 index 0000000..d1e7194 --- /dev/null +++ b/admin_ordering/models.py @@ -0,0 +1,44 @@ +from functools import total_ordering + +from django.core import checks +from django.db import models +from django.db.models import Min +from django.utils.translation import gettext_lazy as _ + + +@total_ordering +class OrderableModel(models.Model): + ordering = models.IntegerField("Kolejność", default=0) + + class Meta: + abstract = True + ordering = ["ordering"] + + def save(self, *args, **kwargs): + if not self.ordering: + min = self.__class__._default_manager.aggregate(m=Min("ordering"))[ + "m"] + self.ordering = (min or 0) - 10 + super().save(*args, **kwargs) + + save.alters_data = True + + def __lt__(self, other): + return ( + self.ordering > other.ordering if isinstance( + other, type(self)) else False + ) + + @classmethod + def check(cls, **kwargs): + errors = super().check(**kwargs) + if not cls._meta.ordering: + errors.append( + checks.Error( + 'The ordering of "%s" is undefined.' % cls._meta.label, + obj=cls, + id="admin_ordering.E002", + hint="Make the inner Meta class inherit OrderableModel.Meta.", + ) + ) + return errors diff --git a/admin_ordering/static/admin_ordering/admin_ordering-icon.svg b/admin_ordering/static/admin_ordering/admin_ordering-icon.svg new file mode 100644 index 0000000..d0a6664 --- /dev/null +++ b/admin_ordering/static/admin_ordering/admin_ordering-icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/admin_ordering/static/admin_ordering/admin_ordering.css b/admin_ordering/static/admin_ordering/admin_ordering.css new file mode 100644 index 0000000..962504c --- /dev/null +++ b/admin_ordering/static/admin_ordering/admin_ordering.css @@ -0,0 +1,86 @@ +.ui-sortable-handle { + cursor: auto; +} + +.ui-sortable-helper { + opacity: 0.8; + border-top: 1px dashed #cccccc; + border-bottom: 1px dashed #cccccc; +} + +.ui-sortable-helper > td, +.ui-sortable-helper > th { + border-bottom: none; +} + +.inline-related.tabular .ui-sortable > tr { + padding: 0; +} + +.inline-related.tabular .ui-sortable-placeholder > td { + display: none; +} + +.admin-ordering-field { + cursor: row-resize; +} + +.admin-ordering-field .admin-ordering-field-input-wrapper { + display: table-cell; + width: 100%; + white-space: nowrap; +} + +.admin-ordering-field .admin-ordering-field-input-wrapper::before { + content: ""; + display: inline-block; + width: 14px; + height: 14px; + background-size: 14px 14px; + background-image: url("admin_ordering-icon.svg"); + background-repeat: no-repeat; + background-position: center center; + vertical-align: middle; + margin-right: 15px; +} + +.admin-ordering-field .admin-ordering-field-input-wrapper input { + margin-bottom: 0; +} + +.admin-ordering-field.admin-ordering-field-hide-input + .admin-ordering-field-input-wrapper::before { + margin-right: 0; +} + +.admin-ordering-field.admin-ordering-field-hide-input + .admin-ordering-field-input-wrapper + input { + visibility: hidden; + pointer-events: none; +} + +.inline-related .admin-ordering-field { + cursor: auto; +} + +.inline-related.has_original .admin-ordering-field, +.inline-related .has_original .admin-ordering-field { + cursor: row-resize; +} + +.inline-related + .admin-ordering-field + .admin-ordering-field-input-wrapper::before { + opacity: 0.3; +} + +.inline-related.has_original + .admin-ordering-field + .admin-ordering-field-input-wrapper::before, +.inline-related + .has_original + .admin-ordering-field + .admin-ordering-field-input-wrapper::before { + opacity: 1; +} diff --git a/admin_ordering/static/admin_ordering/admin_ordering.js b/admin_ordering/static/admin_ordering/admin_ordering.js new file mode 100644 index 0000000..ea3d562 --- /dev/null +++ b/admin_ordering/static/admin_ordering/admin_ordering.js @@ -0,0 +1,170 @@ +/* global django */ +django.jQuery(function ($) { + function updatePlaceholderHeight(ui) { + // set placeholder height equal to item height + ui.placeholder.height(ui.item.outerHeight()) + } + + function hideHorizontalOverflow() { + // hide body horizontal overflow while dragging row + $("body").css("overflow-x", "hidden") + } + + function autoHorizontalOverflow() { + // reset body horizontal overflow + $("body").css("overflow-x", "auto") + } + + function enforceSortableRowsCellsSize(node) { + // enforce row cells size while sorting rows + node.find(">tr").each(function () { + $(this) + .mousedown(function () { + $(this) + .find("td, th") + .each(function () { + $(this).css("width", $(this).width()) + }) + }) + .mouseup(function () { + $(this) + .find("td, th") + .each(function () { + $(this).css("width", "auto") + }) + }) + }) + } + + $(".admin-ordering-context:not(.activated)") + .addClass("activated") + .each(function () { + var $sortable, + $sortableHandle, + $sortableInputWrapper = + '' + + var data = JSON.parse(this.getAttribute("data-context")) + var inputFieldSelector = 'input[name$="-' + data.field + '"]' + + function updateOrdering(nodes) { + var incOrdering = 10 + var maxOrdering = nodes.length * incOrdering + nodes.each(function (index) { + var row = $(this) + var rowOrdering = data.fieldDesc + ? maxOrdering - incOrdering * index + : incOrdering * (index + 1) + row.find(inputFieldSelector).val(rowOrdering) + row.removeClass("row1 row2").addClass(index % 2 ? "row2" : "row1") + }) + } + + if (data.field.indexOf("-") == 0) { + data.field = data.field.substring(1) + data.fieldDesc = true + } else { + data.fieldDesc = false + } + + if (data.tabular) { + $sortable = $("#" + data.prefix + "-group tbody") + $sortableHandle = $sortable.find(".field-" + data.field) + $sortableHandle.addClass("admin-ordering-field") + if (data.fieldHideInput) { + $sortableHandle.addClass("admin-ordering-field-hide-input") + } + $sortableHandle + .find(inputFieldSelector + ':not([type="hidden"])') + .wrap($sortableInputWrapper) + $sortable.sortable({ + items: ">.has_original", + handle: $sortableHandle, + start: function (_event, ui) { + hideHorizontalOverflow() + updatePlaceholderHeight(ui) + // fix ui item height + ui.item.css("height", ui.item.outerHeight()) + }, + update: function (_event, _ui) { + updateOrdering($(".dynamic-" + data.prefix)) + }, + stop: function (_event, ui) { + autoHorizontalOverflow() + // reset ui item height + ui.item.css("height", "auto") + }, + }) + + enforceSortableRowsCellsSize($sortable) + } else if (data.stacked) { + $sortable = $("#" + data.prefix + "-group") + $sortableHandle = $sortable.find(".field-" + data.field) + $sortableHandle.addClass("admin-ordering-field") + if (data.fieldHideInput) { + $sortableHandle.addClass("admin-ordering-field-hide-input") + } + $sortableHandle + .find(inputFieldSelector + ':not([type="hidden"])') + .wrap($sortableInputWrapper) + $sortable.sortable({ + items: ">.has_original,>>.has_original", + handle: $sortableHandle, + start: function (_event, ui) { + hideHorizontalOverflow() + updatePlaceholderHeight(ui) + }, + update: function (_event, _ui) { + updateOrdering($(".dynamic-" + data.prefix)) + }, + stop: function (_event, _ui) { + autoHorizontalOverflow() + }, + }) + } else { + $sortable = $("#result_list tbody") + $sortableHandle = $sortable.find(".field-" + data.field) + $sortableHandle.addClass("admin-ordering-field") + if (data.fieldHideInput) { + $sortableHandle.addClass("admin-ordering-field-hide-input") + } + if (!$sortableHandle.find("input").length) { + return + } + $sortableHandle + .find(inputFieldSelector + ':not([type="hidden"])') + .wrap($sortableInputWrapper) + $sortable.sortable({ + handle: $sortableHandle, + start: function (_event, ui) { + hideHorizontalOverflow() + updatePlaceholderHeight(ui) + }, + update: function (_event, _ui) { + updateOrdering($sortable.find("tr")) + }, + stop: function (_event, _ui) { + autoHorizontalOverflow() + }, + }) + + enforceSortableRowsCellsSize($sortable) + } + + if (data.tabular || data.stacked) { + // Yay, Django 1.9 or better! + $(document).on("formset:added", function newForm(event, $row) { + if (event.detail && event.detail.formsetName) { + // Django 4.1 or better! + if ($(event.target).hasClass("dynamic-" + data.prefix)) { + updateOrdering($(".dynamic-" + data.prefix)) + } + } else { + if ($row.hasClass("dynamic-" + data.prefix)) { + updateOrdering($(".dynamic-" + data.prefix)) + } + } + }) + } + }) +}) diff --git a/admin_ordering/static/admin_ordering/jquery-ui.min.css b/admin_ordering/static/admin_ordering/jquery-ui.min.css new file mode 100755 index 0000000..d229ae3 --- /dev/null +++ b/admin_ordering/static/admin_ordering/jquery-ui.min.css @@ -0,0 +1,6 @@ +/*! jQuery UI - v1.12.1 - 2021-08-12 +* http://jqueryui.com +* Includes: sortable.css +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-sortable-handle{-ms-touch-action:none;touch-action:none} \ No newline at end of file diff --git a/admin_ordering/static/admin_ordering/jquery-ui.min.js b/admin_ordering/static/admin_ordering/jquery-ui.min.js new file mode 100755 index 0000000..12ebedc --- /dev/null +++ b/admin_ordering/static/admin_ordering/jquery-ui.min.js @@ -0,0 +1,6 @@ +/*! jQuery UI - v1.12.1 - 2021-08-12 +* http://jqueryui.com +* Includes: widget.js, data.js, scroll-parent.js, widgets/sortable.js, widgets/mouse.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(django.jQuery)}(function(f){f.ui=f.ui||{};f.ui.version="1.12.1";var o,i=0,h=Array.prototype.slice;f.cleanData=(o=f.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)try{(e=f._data(i,"events"))&&e.remove&&f(i).triggerHandler("remove")}catch(t){}o(t)}),f.widget=function(t,i,e){var s,o,n,r={},h=t.split(".")[0],a=h+"-"+(t=t.split(".")[1]);return e||(e=i,i=f.Widget),f.isArray(e)&&(e=f.extend.apply(null,[{}].concat(e))),f.expr[":"][a.toLowerCase()]=function(t){return!!f.data(t,a)},f[h]=f[h]||{},s=f[h][t],o=f[h][t]=function(t,e){if(!this._createWidget)return new o(t,e);arguments.length&&this._createWidget(t,e)},f.extend(o,s,{version:e.version,_proto:f.extend({},e),_childConstructors:[]}),(n=new i).options=f.widget.extend({},n.options),f.each(e,function(e,s){function o(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}f.isFunction(s)?r[e]=function(){var t,e=this._super,i=this._superApply;return this._super=o,this._superApply=n,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:r[e]=s}),o.prototype=f.widget.extend(n,{widgetEventPrefix:s&&n.widgetEventPrefix||t},r,{constructor:o,namespace:h,widgetName:t,widgetFullName:a}),s?(f.each(s._childConstructors,function(t,e){var i=e.prototype;f.widget(i.namespace+"."+i.widgetName,o,e._proto)}),delete s._childConstructors):i._childConstructors.push(o),f.widget.bridge(t,o),o},f.widget.extend=function(t){for(var e,i,s=h.call(arguments,1),o=0,n=s.length;o",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=f(e||this.defaultElement||this)[0],this.element=f(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=f(),this.hoverable=f(),this.focusable=f(),this.classesElementLookup={},e!==this&&(f.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=f(e.style?e.ownerDocument:e.document||e),this.window=f(this.document[0].defaultView||this.document[0].parentWindow)),this.options=f.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:f.noop,_create:f.noop,_init:f.noop,destroy:function(){var i=this;this._destroy(),f.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:f.noop,widget:function(){return this.element},option:function(t,e){var i,s,o,n=t;if(0===arguments.length)return f.widget.extend({},this.options);if("string"==typeof t)if(n={},t=(i=t.split(".")).shift(),i.length){for(s=n[t]=f.widget.extend({},this.options[t]),o=0;o=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),f.widget("ui.sortable",f.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return e<=t&&t*{ cursor: "+n.cursor+" !important; }").appendTo(o)),n.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",n.opacity)),n.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",n.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!i)for(s=this.containers.length-1;0<=s;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return f.ui.ddmanager&&(f.ui.ddmanager.current=this),f.ui.ddmanager&&!n.dropBehaviour&&f.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var e,i,s,o,n=this.options,r=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageYt[this.floating?"width":"height"]?l&&c:n",i.document[0]);return i._addClass(e,"ui-sortable-placeholder",s||i.currentItem[0].className)._removeClass(e,"ui-sortable-helper"),"tbody"===t?i._createTrPlaceholder(i.currentItem.find("tr").eq(0),f("",i.document[0]).appendTo(e)):"tr"===t?i._createTrPlaceholder(i.currentItem,e):"img"===t&&e.attr("src",i.currentItem.attr("src")),s||e.css("visibility","hidden"),e},update:function(t,e){s&&!o.forcePlaceholderSize||(e.height()||e.height(i.currentItem.innerHeight()-parseInt(i.currentItem.css("paddingTop")||0,10)-parseInt(i.currentItem.css("paddingBottom")||0,10)),e.width()||e.width(i.currentItem.innerWidth()-parseInt(i.currentItem.css("paddingLeft")||0,10)-parseInt(i.currentItem.css("paddingRight")||0,10)))}}),i.placeholder=f(o.placeholder.element.call(i.element,i.currentItem)),i.currentItem.after(i.placeholder),o.placeholder.update(i,i.placeholder)},_createTrPlaceholder:function(t,e){var i=this;t.children().each(function(){f(" ",i.document[0]).attr("colspan",f(this).attr("colspan")||1).appendTo(e)})},_contactContainers:function(t){for(var e,i,s,o,n,r,h,a,l,c=null,u=null,p=this.containers.length-1;0<=p;p--)f.contains(this.currentItem[0],this.containers[p].element[0])||(this._intersectsWith(this.containers[p].containerCache)?c&&f.contains(this.containers[p].element[0],c.element[0])||(c=this.containers[p],u=p):this.containers[p].containerCache.over&&(this.containers[p]._trigger("out",t,this._uiHash(this)),this.containers[p].containerCache.over=0));if(c)if(1===this.containers.length)this.containers[u].containerCache.over||(this.containers[u]._trigger("over",t,this._uiHash(this)),this.containers[u].containerCache.over=1);else{for(i=1e4,s=null,o=(a=c.floating||this._isFloating(this.currentItem))?"left":"top",n=a?"width":"height",l=a?"pageX":"pageY",e=this.items.length-1;0<=e;e--)f.contains(this.containers[u].element[0],this.items[e].item[0])&&this.items[e].item[0]!==this.currentItem[0]&&(r=this.items[e].item.offset()[o],h=!1,t[l]-r>this.items[e][n]/2&&(h=!0),Math.abs(t[l]-r)this.containment[2]&&(i=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(s=this.containment[3]+this.offset.click.top)),e.grid&&(t=this.originalPageY+Math.round((s-this.originalPageY)/e.grid[1])*e.grid[1],s=!this.containment||t-this.offset.click.top>=this.containment[1]&&t-this.offset.click.top<=this.containment[3]?t:t-this.offset.click.top>=this.containment[1]?t-e.grid[1]:t+e.grid[1],t=this.originalPageX+Math.round((i-this.originalPageX)/e.grid[0])*e.grid[0],i=!this.containment||t-this.offset.click.left>=this.containment[0]&&t-this.offset.click.left<=this.containment[2]?t:t-this.offset.click.left>=this.containment[0]?t-e.grid[0]:t+e.grid[0])),{top:s-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():n?0:o.scrollTop()),left:i-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():n?0:o.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var o=this.counter;this._delay(function(){o===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)"auto"!==this._storedCSS[i]&&"static"!==this._storedCSS[i]||(this._storedCSS[i]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();function o(e,i,s){return function(t){s._trigger(e,t,i._uiHash(i))}}for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;0<=i;i--)e||s.push(o("deactivate",this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(o("out",this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(i=0;i +{% block title %}Zarząd | pdlzbs{% endblock %} + {% load static tailwind_tags %} {% block content %} -
-

Zarząd PodlZBS

- - {% if czlonkowie %} -
- {% for member in czlonkowie %} -
-

{{ member.function }}

-

{{ member.name }}

-

{{ member.contact }}

-
- {% endfor %} -
- {% else %} - Brak członków - {% endif %} - -
+
+

Zarząd PodlZBS

+ +
+
+ {% block adm_content %} +

-

{{ statut.title }}

+ {{ statut.title }}
-

+ -
+

Dane adresowe

+

Adres Podlaskiego ZBS - 15-057 Białystok ul. B. Chrobrego 5B m.33 Konto: PKO SA O/B-tok 43 1240 5211 1111 0000 4919 1721 NIP: 542 258 14 53 REGON 050816091 +

+ +

Członkowie

+ {% if czlonkowie %} +
+ {% for member in czlonkowie %} +

+ {{ member.function }} +
+ {{ member.name }} +
+ {{ member.contact }} +
+

+ {% endfor %}
- -

Ogłoszenia

- {% for file in ogloszenia %} - - {% empty %} - Brak ogłoszeń - {% endfor %} - -

Protokoły / Ustawy

- {% for file in protokoly %} - - {% empty %} - Brak protokołów / ustaw - {% endfor %} - -

Regulaminy

- {% for file in regulaminy %} - - {% empty %} - Brak regulaminów - {% endfor %} + {% else %} +

Brak członków

+ {% endif %} {% endblock %}
{% endblock %} diff --git a/core/templates/administration/announcements.html b/core/templates/administration/announcements.html new file mode 100644 index 0000000..d97cd27 --- /dev/null +++ b/core/templates/administration/announcements.html @@ -0,0 +1,20 @@ +{% extends 'administration.html' %} + +{% block title %}Zarząd - Ogłoszenia | pdlzbs{% endblock %} + +{% load static tailwind_tags %} {% block adm_content %} +

Ogłoszenia zarządu

+ +{% if ogloszenia %} + +{% else %} +

Brak ogłoszeń

+{% endif %} {% endblock %} diff --git a/core/templates/administration/protocols.html b/core/templates/administration/protocols.html new file mode 100644 index 0000000..1ca219d --- /dev/null +++ b/core/templates/administration/protocols.html @@ -0,0 +1,35 @@ +{% extends 'administration.html' %} + +{% block title %}Zarząd - Protokoły i Uchwały | pdlzbs{% endblock %} + +{% load static tailwind_tags %} {% block adm_content %} +

Protokoły i Uchwały

+{% if protokoly %} + + + + + + + + + {% for file in protokoly %} + + + + + {% endfor %} + +
DokumentRok
+ {{ file }} +
+ {{ file.extra }} +
{{ file.year }}
+{% else %} +

Brak protokołów / ustaw

+{% endif %} {% endblock %} diff --git a/core/templates/administration/regulations.html b/core/templates/administration/regulations.html new file mode 100644 index 0000000..bb31200 --- /dev/null +++ b/core/templates/administration/regulations.html @@ -0,0 +1,19 @@ +{% extends 'administration.html' %} + +{% block title %}Zarząd - Regulaminy | pdlzbs{% endblock %} + +{% load static tailwind_tags %} {% block adm_content %} +

Regulaminy

+{% if regulaminy %} + +{% else %} +

Brak regulaminów

+{% endif %} {% endblock %} diff --git a/core/templates/administration/rodos.html b/core/templates/administration/rodos.html new file mode 100644 index 0000000..d7322aa --- /dev/null +++ b/core/templates/administration/rodos.html @@ -0,0 +1,20 @@ +{% extends 'administration.html' %} + +{% block title %}Zarząd - RODO | pdlzbs {% endblock %} + +{% load static tailwind_tags %} {% block adm_content %} +

Dokumenty RODO

+{% if rodos %} +
    + {% for file in rodos %} +
  • +

    + Informacje o przetwarzaniu danych osobowych zawodników przez + {{ file.who }} +

    +
  • + {% endfor %} +
+{% else %} +

Brak dokumentów

+{% endif %} {% endblock %} diff --git a/core/templates/base.html b/core/templates/base.html index 13f33b1..9090828 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -18,13 +18,13 @@ {% tailwind_css %} - -
+ +
-
Logo
+
- Podlaski Związek Brydża Sportowego +

Podlaski Związek
Brydża Sportowego

-
+
+
{% block content %}{% endblock %}
- © {% now "Y" %} Mikołaj Kubiczek +
© {% now "Y" %} Mikołaj Kubiczek
diff --git a/core/templates/calendar.html b/core/templates/calendar.html index df39e42..d8001f4 100644 --- a/core/templates/calendar.html +++ b/core/templates/calendar.html @@ -1,5 +1,5 @@ -{% extends 'base.html' %} {% block title %}Strona główna | pdlzbs{% endblock %} -{% load static tailwind_tags %} {% block content %} +{% extends 'base.html' %} {% block title %}Kalendarz | pdlzbs{% endblock %} {% +load static tailwind_tags %} {% block content %}
{% for calendar in calendars %}
+{% block title %}Grand Prix Białegostoku | pdlzbs{% endblock %} + {% load static tailwind_tags %} {% block content %}

diff --git a/core/templates/home.html b/core/templates/home.html index 1925389..8ebad7f 100644 --- a/core/templates/home.html +++ b/core/templates/home.html @@ -1,25 +1,28 @@ {% extends 'base.html' %} {% block title %}Strona główna | pdlzbs{% endblock %} {% load static tailwind_tags %} {% block content %} -
-
+
+

Grand Prix Województwa

- {{ gpw.content | safe }} +
{{ gpw.content | safe }}
-
+

Aktualności PodlZBS

+
{% for post in posts %} -
-

{{ post.title }}

- {{ post.content | safe }} +
+

{{ post.title }}

+
{{ post.content | safe }}
- {% empty %} - Więcej wpisów nie ma + {% if not forloop.last %} +
+ {% endif %} {% empty %} +

Więcej wpisów nie ma

{% endfor %}
diff --git a/core/templates/league.html b/core/templates/league.html index 449a5ad..35dbba3 100644 --- a/core/templates/league.html +++ b/core/templates/league.html @@ -1,16 +1,24 @@ -{% extends 'base.html' %} {% block title %}Strona główna | pdlzbs{% endblock %} +{% extends 'base.html' %} + +{% block title %}Liga | pdlzbs{% endblock %} + {% load static tailwind_tags %} {% block content %} -
+

Wyniki III ligi

+{% if leagues %} +
+
  • + +

    Wyniki III ligi DMP {{ league.year }}-{{ league.year | add:"1" }}

    +
    +
  • + {% endfor %} + +{% else %} +

    Brak wyników

    +{% endif %} {% endblock %} diff --git a/core/templates/membership.html b/core/templates/membership.html index a330ec1..34c0774 100644 --- a/core/templates/membership.html +++ b/core/templates/membership.html @@ -1,13 +1,25 @@ -{% extends 'base.html' %} {% block title %}Strona główna | pdlzbs{% endblock %} +{% extends 'base.html' %} + +{% block title %}Składki Członkowskie | pdlzbs{% endblock %} + {% load static tailwind_tags %} {% block content %} -
    +

    + Składki członkowskie +

    +{% if memberships %} +
      {% for membership in memberships %} - - {% empty %} - Brak dokumentów - {% endfor %} {% endblock %} -
    + + {% endfor %} + +{% else %} +

    Brak dokumentów

    +{% endif %} {% endblock %} diff --git a/core/templates/rodo.html b/core/templates/rodo.html deleted file mode 100644 index d9e1a1e..0000000 --- a/core/templates/rodo.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends 'base.html' %} {% block title %}Strona główna | pdlzbs{% endblock %} -{% load static tailwind_tags %} {% block content %} -
    - {% for rodo in rodos %} -
    -

    - Informacje o przetwarzaniu danych osobowych zawodników przez - {{ rodo.who }} -

    -
    - {% empty %} - Brak dokumentów - {% endfor %} -
    -{% endblock %} diff --git a/core/urls.py b/core/urls.py index 9522c73..e326455 100644 --- a/core/urls.py +++ b/core/urls.py @@ -4,7 +4,14 @@ from .views import * urlpatterns = [ path('', HomeView.as_view(), name='home'), path('zarzad', AdministrationView.as_view(), name='administration'), - path('rodo', RODOView.as_view(), name='rodo'), + path('zarzad/ogloszenia', AdministrationAnnouncementsView.as_view(), + name='administration_announcements'), + path('zarzad/protokolyiuchwaly', AdministrationProtocolsView.as_view(), + name='administration_protocols'), + path('zarzad/regulaminy', AdministrationRegulationsView.as_view(), + name='administration_regulations'), + path('zarzad/rodo', AdministrationRODOView.as_view(), + name='administration_rodos'), path('liga', LeagueView.as_view(), name='league'), path('kalendarz', CalendarView.as_view(), name='calendar'), path('grandprix', GrandPrixView.as_view(), name='gpx'), diff --git a/core/views.py b/core/views.py index 25b5b76..1b7b7ad 100644 --- a/core/views.py +++ b/core/views.py @@ -35,22 +35,65 @@ class AdministrationView(TemplateView): context = { **context, - 'czlonkowie': AdministrationMember.objects.all(), - 'statut': AdministrationStatute.objects.first(), - 'ogloszenia': AdministrationAnnouncement.objects.all(), - 'protokoly': AdministrationProtocol.objects.all(), - 'regulaminy': AdministrationRegulation.objects.all(), + 'czlonkowie': Member.objects.all(), + 'statut': Statute.objects.first(), } return context -class RODOView(TemplateView): - template_name = 'rodo.html' +class AdministrationAnnouncementsView(TemplateView): + template_name = 'administration/announcements.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['rodos'] = RODO.objects.all() + + context = { + **context, + 'ogloszenia': Announcement.objects.all(), + } + + return context + + +class AdministrationProtocolsView(TemplateView): + template_name = 'administration/protocols.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + context = { + **context, + 'protokoly': Protocol.objects.all(), + } + + return context + + +class AdministrationRegulationsView(TemplateView): + template_name = 'administration/regulations.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + context = { + **context, + 'regulaminy': Regulation.objects.all(), + } + + return context + + +class AdministrationRODOView(TemplateView): + template_name = 'administration/rodos.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + context = { + **context, + 'rodos': RODO.objects.all(), + } return context diff --git a/db/administration/admin.py b/db/administration/admin.py index 4a5940e..587d46f 100644 --- a/db/administration/admin.py +++ b/db/administration/admin.py @@ -5,9 +5,31 @@ from .models import * # Register your models here. -@admin.register(AdministrationMember) -class AdministrationMemberModelAdmin(OrderableAdmin, admin.ModelAdmin): +@admin.register(Member) +class MemberModelAdmin(OrderableAdmin, admin.ModelAdmin): list_display = ['__str__', 'ordering'] list_editable = ['ordering'] ordering_field_hide_input = True exclude = ['ordering'] + + +class OrderableModelAdmin(OrderableAdmin, admin.ModelAdmin): + list_display = ['title', 'year', 'ordering'] + list_editable = ['ordering'] + ordering_field_hide_input = True + exclude = ['ordering'] + + +@admin.register(Announcement) +class AnnouncementModelAdmin(OrderableModelAdmin): + list_display = ['title', 'ordering'] + + +@admin.register(Protocol) +class ProtocolModelAdmin(OrderableModelAdmin): + pass + + +@admin.register(Regulation) +class RegulationModelAdmin(OrderableModelAdmin): + list_display = ['title', 'ordering'] diff --git a/db/administration/migrations/0002_announcement_protocol_regulation_statute_and_more.py b/db/administration/migrations/0002_announcement_protocol_regulation_statute_and_more.py new file mode 100644 index 0000000..e8c9c28 --- /dev/null +++ b/db/administration/migrations/0002_announcement_protocol_regulation_statute_and_more.py @@ -0,0 +1,90 @@ +# Generated by Django 4.0.5 on 2022-07-23 21:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Announcement', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('year', models.IntegerField(blank=True, null=True, verbose_name='Rok')), + ('title', models.CharField(max_length=250, verbose_name='Tytuł')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('attachment', models.FileField(upload_to='zarzad_ogloszenia', verbose_name='Plik pdf')), + ], + options={ + 'verbose_name': 'Ogłoszenie', + 'verbose_name_plural': 'Ogłoszenia', + }, + ), + migrations.CreateModel( + name='Protocol', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('year', models.IntegerField(blank=True, null=True, verbose_name='Rok')), + ('title', models.CharField(max_length=250, verbose_name='Tytuł')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('attachment', models.FileField(upload_to='zarzad_protokolyuchwaly', verbose_name='Plik pdf')), + ], + options={ + 'verbose_name': 'Protokół / Uchwała', + 'verbose_name_plural': 'Protokoły / Uchwały', + }, + ), + migrations.CreateModel( + name='Regulation', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('year', models.IntegerField(blank=True, null=True, verbose_name='Rok')), + ('title', models.CharField(max_length=250, verbose_name='Tytuł')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('attachment', models.FileField(upload_to='zarzad_regulaminy', verbose_name='Plik pdf')), + ], + options={ + 'verbose_name': 'Regulamin', + 'verbose_name_plural': 'Regulaminy', + }, + ), + migrations.CreateModel( + name='Statute', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('year', models.IntegerField(blank=True, null=True, verbose_name='Rok')), + ('title', models.CharField(max_length=250, verbose_name='Tytuł')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('attachment', models.FileField(upload_to='zarzad_statuty', verbose_name='Plik pdf')), + ], + options={ + 'verbose_name': 'Statut', + 'verbose_name_plural': 'Statuty', + }, + ), + migrations.RenameModel( + old_name='AdministrationMember', + new_name='Member', + ), + migrations.DeleteModel( + name='AdministrationAnnouncement', + ), + migrations.DeleteModel( + name='AdministrationProtocol', + ), + migrations.DeleteModel( + name='AdministrationRegulation', + ), + migrations.DeleteModel( + name='AdministrationStatute', + ), + migrations.AlterField( + model_name='rodo', + name='attachment', + field=models.FileField(upload_to='zarzad_rodo', verbose_name='Plik pdf'), + ), + ] diff --git a/db/administration/migrations/0003_alter_announcement_attachment_and_more.py b/db/administration/migrations/0003_alter_announcement_attachment_and_more.py new file mode 100644 index 0000000..d517e95 --- /dev/null +++ b/db/administration/migrations/0003_alter_announcement_attachment_and_more.py @@ -0,0 +1,34 @@ +# Generated by Django 4.0.5 on 2022-07-23 21:33 + +import db.administration.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0002_announcement_protocol_regulation_statute_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='announcement', + name='attachment', + field=models.FileField(upload_to=db.administration.models.AttachmentModel._upload_to, verbose_name='Plik pdf'), + ), + migrations.AlterField( + model_name='protocol', + name='attachment', + field=models.FileField(upload_to=db.administration.models.AttachmentModel._upload_to, verbose_name='Plik pdf'), + ), + migrations.AlterField( + model_name='regulation', + name='attachment', + field=models.FileField(upload_to=db.administration.models.AttachmentModel._upload_to, verbose_name='Plik pdf'), + ), + migrations.AlterField( + model_name='statute', + name='attachment', + field=models.FileField(upload_to=db.administration.models.AttachmentModel._upload_to, verbose_name='Plik pdf'), + ), + ] diff --git a/db/administration/migrations/0004_alter_announcement_options_alter_protocol_options_and_more.py b/db/administration/migrations/0004_alter_announcement_options_alter_protocol_options_and_more.py new file mode 100644 index 0000000..10185f1 --- /dev/null +++ b/db/administration/migrations/0004_alter_announcement_options_alter_protocol_options_and_more.py @@ -0,0 +1,49 @@ +# Generated by Django 4.0.5 on 2022-07-23 21:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0003_alter_announcement_attachment_and_more'), + ] + + operations = [ + migrations.AlterModelOptions( + name='announcement', + options={'ordering': ['ordering'], 'verbose_name': 'Ogłoszenie', 'verbose_name_plural': 'Ogłoszenia'}, + ), + migrations.AlterModelOptions( + name='protocol', + options={'ordering': ['ordering'], 'verbose_name': 'Protokół / Uchwała', 'verbose_name_plural': 'Protokoły / Uchwały'}, + ), + migrations.AlterModelOptions( + name='regulation', + options={'ordering': ['ordering'], 'verbose_name': 'Regulamin', 'verbose_name_plural': 'Regulaminy'}, + ), + migrations.AlterModelOptions( + name='statute', + options={'ordering': ['ordering'], 'verbose_name': 'Statut', 'verbose_name_plural': 'Statuty'}, + ), + migrations.AddField( + model_name='announcement', + name='ordering', + field=models.PositiveIntegerField(default=0, verbose_name='ordering'), + ), + migrations.AddField( + model_name='protocol', + name='ordering', + field=models.PositiveIntegerField(default=0, verbose_name='ordering'), + ), + migrations.AddField( + model_name='regulation', + name='ordering', + field=models.PositiveIntegerField(default=0, verbose_name='ordering'), + ), + migrations.AddField( + model_name='statute', + name='ordering', + field=models.PositiveIntegerField(default=0, verbose_name='ordering'), + ), + ] diff --git a/db/administration/migrations/0005_alter_announcement_ordering_alter_member_ordering_and_more.py b/db/administration/migrations/0005_alter_announcement_ordering_alter_member_ordering_and_more.py new file mode 100644 index 0000000..6d64d40 --- /dev/null +++ b/db/administration/migrations/0005_alter_announcement_ordering_alter_member_ordering_and_more.py @@ -0,0 +1,38 @@ +# Generated by Django 4.0.5 on 2022-07-23 22:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0004_alter_announcement_options_alter_protocol_options_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='announcement', + name='ordering', + field=models.PositiveIntegerField(default=0, verbose_name='Kolejność'), + ), + migrations.AlterField( + model_name='member', + name='ordering', + field=models.PositiveIntegerField(default=0, verbose_name='Kolejność'), + ), + migrations.AlterField( + model_name='protocol', + name='ordering', + field=models.PositiveIntegerField(default=0, verbose_name='Kolejność'), + ), + migrations.AlterField( + model_name='regulation', + name='ordering', + field=models.PositiveIntegerField(default=0, verbose_name='Kolejność'), + ), + migrations.AlterField( + model_name='statute', + name='ordering', + field=models.PositiveIntegerField(default=0, verbose_name='Kolejność'), + ), + ] diff --git a/db/administration/migrations/0006_alter_announcement_options_alter_protocol_options_and_more.py b/db/administration/migrations/0006_alter_announcement_options_alter_protocol_options_and_more.py new file mode 100644 index 0000000..32c79b8 --- /dev/null +++ b/db/administration/migrations/0006_alter_announcement_options_alter_protocol_options_and_more.py @@ -0,0 +1,54 @@ +# Generated by Django 4.0.5 on 2022-07-23 22:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0005_alter_announcement_ordering_alter_member_ordering_and_more'), + ] + + operations = [ + migrations.AlterModelOptions( + name='announcement', + options={'ordering': ['-year', 'ordering'], 'verbose_name': 'Ogłoszenie', 'verbose_name_plural': 'Ogłoszenia'}, + ), + migrations.AlterModelOptions( + name='protocol', + options={'ordering': ['-year', 'ordering'], 'verbose_name': 'Protokół / Uchwała', 'verbose_name_plural': 'Protokoły / Uchwały'}, + ), + migrations.AlterModelOptions( + name='regulation', + options={'ordering': ['-year', 'ordering'], 'verbose_name': 'Regulamin', 'verbose_name_plural': 'Regulaminy'}, + ), + migrations.AlterModelOptions( + name='statute', + options={'ordering': ['-year', 'ordering'], 'verbose_name': 'Statut', 'verbose_name_plural': 'Statuty'}, + ), + migrations.AlterField( + model_name='announcement', + name='ordering', + field=models.IntegerField(default=0, verbose_name='Kolejność'), + ), + migrations.AlterField( + model_name='member', + name='ordering', + field=models.IntegerField(default=0, verbose_name='Kolejność'), + ), + migrations.AlterField( + model_name='protocol', + name='ordering', + field=models.IntegerField(default=0, verbose_name='Kolejność'), + ), + migrations.AlterField( + model_name='regulation', + name='ordering', + field=models.IntegerField(default=0, verbose_name='Kolejność'), + ), + migrations.AlterField( + model_name='statute', + name='ordering', + field=models.IntegerField(default=0, verbose_name='Kolejność'), + ), + ] diff --git a/db/administration/migrations/0007_alter_announcement_options_alter_regulation_options_and_more.py b/db/administration/migrations/0007_alter_announcement_options_alter_regulation_options_and_more.py new file mode 100644 index 0000000..7315fe4 --- /dev/null +++ b/db/administration/migrations/0007_alter_announcement_options_alter_regulation_options_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.0.5 on 2022-07-23 22:53 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0006_alter_announcement_options_alter_protocol_options_and_more'), + ] + + operations = [ + migrations.AlterModelOptions( + name='announcement', + options={'ordering': ['ordering'], 'verbose_name': 'Ogłoszenie', 'verbose_name_plural': 'Ogłoszenia'}, + ), + migrations.AlterModelOptions( + name='regulation', + options={'ordering': ['ordering'], 'verbose_name': 'Regulamin', 'verbose_name_plural': 'Regulaminy'}, + ), + migrations.RemoveField( + model_name='announcement', + name='year', + ), + migrations.RemoveField( + model_name='regulation', + name='year', + ), + ] diff --git a/db/administration/migrations/0008_alter_statute_options_remove_statute_created_at_and_more.py b/db/administration/migrations/0008_alter_statute_options_remove_statute_created_at_and_more.py new file mode 100644 index 0000000..d9e8c72 --- /dev/null +++ b/db/administration/migrations/0008_alter_statute_options_remove_statute_created_at_and_more.py @@ -0,0 +1,34 @@ +# Generated by Django 4.0.5 on 2022-07-23 22:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0007_alter_announcement_options_alter_regulation_options_and_more'), + ] + + operations = [ + migrations.AlterModelOptions( + name='statute', + options={'verbose_name': 'Statut', 'verbose_name_plural': 'Statut'}, + ), + migrations.RemoveField( + model_name='statute', + name='created_at', + ), + migrations.RemoveField( + model_name='statute', + name='ordering', + ), + migrations.RemoveField( + model_name='statute', + name='year', + ), + migrations.AlterField( + model_name='statute', + name='attachment', + field=models.FileField(upload_to='zarzad_statuty', verbose_name='Plik pdf'), + ), + ] diff --git a/db/administration/migrations/0009_protocol_extra.py b/db/administration/migrations/0009_protocol_extra.py new file mode 100644 index 0000000..d0690ba --- /dev/null +++ b/db/administration/migrations/0009_protocol_extra.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.5 on 2022-07-23 23:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0008_alter_statute_options_remove_statute_created_at_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='protocol', + name='extra', + field=models.TextField(blank=True, default='', verbose_name='Dodatkowy opis'), + ), + ] diff --git a/db/administration/models.py b/db/administration/models.py index 67c42fe..e494e52 100644 --- a/db/administration/models.py +++ b/db/administration/models.py @@ -1,55 +1,36 @@ from django.db import models from admin_ordering.models import OrderableModel +from core.utils import SingletonModel # Create your models here. -class AttachmentModel(models.Model): - year = models.IntegerField('Rok', blank=True, null=True) +class AttachmentModel(OrderableModel): + upload_to = 'zalaczniki' title = models.CharField('Tytuł', max_length=250) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.title - class Meta: + def _upload_to(self, filename): + return f'zarzad_{self.upload_to}/{filename}' + + attachment = models.FileField('Plik pdf', upload_to=_upload_to) + + class Meta(OrderableModel.Meta): abstract = True - ordering = ['-created_at'] -class AdministrationStatute(AttachmentModel): - attachment = models.FileField('Plik pdf', upload_to='statutes') +class Announcement(AttachmentModel): + upload_to = 'ogloszenia' - class Meta: - verbose_name = 'Statut' - verbose_name_plural = 'Statuty' - - -class AdministrationAnnouncement(AttachmentModel): - attachment = models.FileField('Plik pdf', upload_to='announcements') - - class Meta: + class Meta(OrderableModel.Meta): verbose_name = 'Ogłoszenie' verbose_name_plural = 'Ogłoszenia' -class AdministrationProtocol(AttachmentModel): - attachment = models.FileField('Plik pdf', upload_to='protocols') - - class Meta: - verbose_name = 'Protokół / Uchwała' - verbose_name_plural = 'Protokoły / Uchwały' - - -class AdministrationRegulation(AttachmentModel): - attachment = models.FileField('Plik pdf', upload_to='regulations') - - class Meta: - verbose_name = 'Regulamin' - verbose_name_plural = 'Regulaminy' - - -class AdministrationMember(OrderableModel): +class Member(OrderableModel): name = models.CharField('Imię i nazwisko', max_length=512) contact = models.CharField('Dane kontaktowe', max_length=512) function = models.CharField('Funkcja', max_length=512) @@ -62,10 +43,29 @@ class AdministrationMember(OrderableModel): verbose_name_plural = 'Członkowie' +class Protocol(AttachmentModel): + upload_to = 'protokolyuchwaly' + extra = models.TextField('Dodatkowy opis', default='', blank=True) + year = models.IntegerField('Rok', blank=True, null=True) + + class Meta(OrderableModel.Meta): + verbose_name = 'Protokół / Uchwała' + verbose_name_plural = 'Protokoły / Uchwały' + ordering = ['-year', 'ordering'] + + +class Regulation(AttachmentModel): + upload_to = 'regulaminy' + + class Meta(OrderableModel.Meta): + verbose_name = 'Regulamin' + verbose_name_plural = 'Regulaminy' + + class RODO(models.Model): who = models.CharField( 'Przez kogo przetwarzane dane osobowe?', max_length=512) - attachment = models.FileField('Plik pdf', upload_to='rodo') + attachment = models.FileField('Plik pdf', upload_to='zarzad_rodo') def __str__(self): return f'RODO - {self.who}' @@ -73,3 +73,15 @@ class RODO(models.Model): class Meta: verbose_name = 'Dokument RODO' verbose_name_plural = 'Dokumenty RODO' + + +class Statute(SingletonModel): + title = models.CharField('Tytuł', max_length=250) + attachment = models.FileField('Plik pdf', upload_to='zarzad_statuty') + + def __str__(self): + return self.title + + class Meta: + verbose_name = 'Statut' + verbose_name_plural = 'Statut' diff --git a/requirements.txt b/requirements.txt index 67250b8..7a4e87a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,5 @@ django-browser-reload django-tailwind django-tinymce django-filebrowser-no-grappelli -django-admin-ordering django-htmlmin django-cleanup \ No newline at end of file diff --git a/theme/static/css/dist/styles.css b/theme/static/css/dist/styles.css index 6bb64ed..bafd6b7 100644 --- a/theme/static/css/dist/styles.css +++ b/theme/static/css/dist/styles.css @@ -1083,39 +1083,88 @@ select { .nav-item > a { display: inline-block; + border-radius: 0.375rem; border-width: 1px; - border-color: rgb(167 243 208 / var(--tw-border-opacity)); + border-color: rgb(187 247 208 / var(--tw-border-opacity)); --tw-border-opacity: 1; - border-top-color: rgb(16 185 129 / var(--tw-border-opacity)); + border-bottom-color: rgb(34 197 94 / var(--tw-border-opacity)); --tw-bg-opacity: 1; - background-color: rgb(209 250 229 / var(--tw-bg-opacity)); + background-color: rgb(220 252 231 / var(--tw-bg-opacity)); padding-left: 0.5rem; padding-right: 0.5rem; - padding-top: 10px; - padding-bottom: 0.5rem; + padding-bottom: 10px; + padding-top: 0.5rem; --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-text-decoration-color, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-text-decoration-color, -webkit-backdrop-filter; + transition-duration: 300ms; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); } .nav-item > a:hover { - border-top-width: 4px; - border-color: rgb(110 231 183 / var(--tw-border-opacity)); + border-bottom-width: 4px; + border-color: rgb(134 239 172 / var(--tw-border-opacity)); --tw-border-opacity: 1; - border-top-color: rgb(5 150 105 / var(--tw-border-opacity)); + border-bottom-color: rgb(22 163 74 / var(--tw-border-opacity)); --tw-bg-opacity: 1; - background-color: rgb(167 243 208 / var(--tw-bg-opacity)); - padding-top: 7px; + background-color: rgb(187 247 208 / var(--tw-bg-opacity)); + padding-bottom: 7px; } .active > a { - border-top-width: 4px; - border-color: rgb(110 231 183 / var(--tw-border-opacity)); + border-bottom-width: 4px; + border-color: rgb(134 239 172 / var(--tw-border-opacity)); --tw-border-opacity: 1; - border-top-color: rgb(5 150 105 / var(--tw-border-opacity)); + border-bottom-color: rgb(22 163 74 / var(--tw-border-opacity)); --tw-bg-opacity: 1; - background-color: rgb(110 231 183 / var(--tw-bg-opacity)); - padding-top: 7px; + background-color: rgb(134 239 172 / var(--tw-bg-opacity)); + padding-bottom: 7px; +} + +.adm_nav-item > a { + display: inline-block; + border-radius: 0.375rem; + border-width: 1px; + border-color: rgb(191 219 254 / var(--tw-border-opacity)); + --tw-border-opacity: 1; + border-bottom-color: rgb(59 130 246 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(219 234 254 / var(--tw-bg-opacity)); + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-bottom: 10px; + padding-top: 0.5rem; + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-text-decoration-color, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-text-decoration-color, -webkit-backdrop-filter; + transition-duration: 300ms; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.adm_nav-item > a:hover { + border-bottom-width: 4px; + border-color: rgb(147 197 253 / var(--tw-border-opacity)); + --tw-border-opacity: 1; + border-bottom-color: rgb(37 99 235 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(191 219 254 / var(--tw-bg-opacity)); + padding-bottom: 7px; +} + +.adm_active > a { + border-bottom-width: 4px; + border-color: rgb(147 197 253 / var(--tw-border-opacity)); + --tw-border-opacity: 1; + border-bottom-color: rgb(37 99 235 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(147 197 253 / var(--tw-bg-opacity)); + padding-bottom: 7px; } .sr-only { @@ -1165,6 +1214,15 @@ select { margin-bottom: 0px; } +.my-4 { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.mb-2 { + margin-bottom: 0.5rem; +} + .mb-0 { margin-bottom: 0px; } @@ -1181,10 +1239,34 @@ select { margin-bottom: 2.5rem; } +.mb-6 { + margin-bottom: 1.5rem; +} + +.mb-8 { + margin-bottom: 2rem; +} + +.mt-0 { + margin-top: 0px; +} + +.mb-auto { + margin-bottom: auto; +} + +.box-content { + box-sizing: content-box; +} + .block { display: block; } +.inline-block { + display: inline-block; +} + .inline { display: inline; } @@ -1209,10 +1291,6 @@ select { display: none; } -.h-screen { - height: 100vh; -} - .h-\[40px\] { height: 40px; } @@ -1221,6 +1299,14 @@ select { height: 100%; } +.h-screen { + height: 100vh; +} + +.h-auto { + height: auto; +} + .max-h-12 { max-height: 3rem; } @@ -1229,6 +1315,10 @@ select { min-height: 125px; } +.w-screen { + width: 100vw; +} + .w-full { width: 100%; } @@ -1241,6 +1331,18 @@ select { min-width: 145px; } +.max-w-screen-lg { + max-width: 1024px; +} + +.max-w-full { + max-width: 100%; +} + +.grow-0 { + flex-grow: 0; +} + .basis-3\/5 { flex-basis: 60%; } @@ -1249,6 +1351,18 @@ select { flex-basis: 40%; } +.basis-1\/2 { + flex-basis: 50%; +} + +.basis-1 { + flex-basis: 0.25rem; +} + +.basis-full { + flex-basis: 100%; +} + .border-collapse { border-collapse: collapse; } @@ -1281,26 +1395,42 @@ select { justify-content: center; } +.justify-between { + justify-content: space-between; +} + .justify-around { justify-content: space-around; } -.gap-4 { - gap: 1rem; -} - -.gap-3 { - gap: 0.75rem; -} - .gap-6 { gap: 1.5rem; } +.gap-3 { + gap: 0.75rem; +} + +.gap-4 { + gap: 1rem; +} + +.gap-8 { + gap: 2rem; +} + .self-end { align-self: flex-end; } +.self-center { + align-self: center; +} + +.rounded-lg { + border-radius: 0.5rem; +} + .rounded-md { border-radius: 0.375rem; } @@ -1337,9 +1467,44 @@ select { border-color: rgb(168 162 158 / var(--tw-border-opacity)); } -.bg-gray-50 { - --tw-bg-opacity: 1; - background-color: rgb(249 250 251 / var(--tw-bg-opacity)); +.border-rose-200 { + --tw-border-opacity: 1; + border-color: rgb(254 205 211 / var(--tw-border-opacity)); +} + +.border-pink-200 { + --tw-border-opacity: 1; + border-color: rgb(251 207 232 / var(--tw-border-opacity)); +} + +.border-indigo-200 { + --tw-border-opacity: 1; + border-color: rgb(199 210 254 / var(--tw-border-opacity)); +} + +.border-sky-200 { + --tw-border-opacity: 1; + border-color: rgb(186 230 253 / var(--tw-border-opacity)); +} + +.border-blue-400 { + --tw-border-opacity: 1; + border-color: rgb(96 165 250 / var(--tw-border-opacity)); +} + +.border-blue-200 { + --tw-border-opacity: 1; + border-color: rgb(191 219 254 / var(--tw-border-opacity)); +} + +.border-blue-100 { + --tw-border-opacity: 1; + border-color: rgb(219 234 254 / var(--tw-border-opacity)); +} + +.border-stone-300 { + --tw-border-opacity: 1; + border-color: rgb(214 211 209 / var(--tw-border-opacity)); } .bg-white { @@ -1347,22 +1512,52 @@ select { background-color: rgb(255 255 255 / var(--tw-bg-opacity)); } +.bg-cyan-50 { + --tw-bg-opacity: 1; + background-color: rgb(236 254 255 / var(--tw-bg-opacity)); +} + .bg-stone-50 { --tw-bg-opacity: 1; background-color: rgb(250 250 249 / var(--tw-bg-opacity)); } -.p-2 { - padding: 0.5rem; +.bg-pink-100 { + --tw-bg-opacity: 1; + background-color: rgb(252 231 243 / var(--tw-bg-opacity)); +} + +.bg-rose-100 { + --tw-bg-opacity: 1; + background-color: rgb(255 228 230 / var(--tw-bg-opacity)); +} + +.bg-gray-50 { + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity)); +} + +.bg-sky-100 { + --tw-bg-opacity: 1; + background-color: rgb(224 242 254 / var(--tw-bg-opacity)); +} + +.bg-indigo-100 { + --tw-bg-opacity: 1; + background-color: rgb(224 231 255 / var(--tw-bg-opacity)); +} + +.bg-blue-50 { + --tw-bg-opacity: 1; + background-color: rgb(239 246 255 / var(--tw-bg-opacity)); } .p-4 { padding: 1rem; } -.py-4 { - padding-top: 1rem; - padding-bottom: 1rem; +.p-2 { + padding: 0.5rem; } .px-4 { @@ -1375,6 +1570,16 @@ select { padding-bottom: 0.75rem; } +.py-4 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + .pb-1 { padding-bottom: 0.25rem; } @@ -1387,28 +1592,45 @@ select { padding-bottom: 1.5rem; } +.text-left { + text-align: left; +} + .text-center { text-align: center; } +.text-right { + text-align: right; +} + .font-serif { font-family: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif; } -.text-5xl { - font-size: 3rem; -} - .text-4xl { font-size: 2.25rem; + line-height: 2.5rem; } .text-xl { font-size: 1.25rem; + line-height: 1.75rem; +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; } .text-3xl { font-size: 1.875rem; + line-height: 2.25rem; +} + +.text-xs { + font-size: 0.75rem; + line-height: 1rem; } .text-\[15px\] { @@ -1423,24 +1645,29 @@ select { font-size: 2.25rem; } -.font-semibold { - font-weight: 600; +.text-5xl { + font-size: 3rem; + line-height: 1; } -.font-bold { - font-weight: 700; +.font-medium { + font-weight: 500; } .font-light { font-weight: 300; } +.font-bold { + font-weight: 700; +} + .font-extrabold { font-weight: 800; } -.font-medium { - font-weight: 500; +.font-semibold { + font-weight: 600; } .lowercase { @@ -1451,14 +1678,14 @@ select { font-style: italic; } -.leading-normal { - line-height: 1.5; -} - .leading-5 { line-height: 1.25rem; } +.leading-normal { + line-height: 1.5; +} + .tracking-normal { letter-spacing: 0em; } @@ -1468,28 +1695,23 @@ select { color: rgb(255 255 255 / var(--tw-text-opacity)); } -.underline { - -webkit-text-decoration-line: underline; - text-decoration-line: underline; -} - .antialiased { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } -.shadow-lg { - --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - .shadow-md { --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + .outline { outline-style: solid; } @@ -1503,6 +1725,18 @@ select { filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } +.transition { + transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-text-decoration-color, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-text-decoration-color, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.duration-300 { + transition-duration: 300ms; +} + .ease-in-out { transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); } @@ -1516,46 +1750,94 @@ select { display: block; } -.hover\:border-stone-200:hover { +.hover\:border-pink-300:hover { --tw-border-opacity: 1; - border-color: rgb(231 229 228 / var(--tw-border-opacity)); + border-color: rgb(249 168 212 / var(--tw-border-opacity)); } -.hover\:bg-stone-100:hover { +.hover\:border-rose-300:hover { + --tw-border-opacity: 1; + border-color: rgb(253 164 175 / var(--tw-border-opacity)); +} + +.hover\:border-sky-300:hover { + --tw-border-opacity: 1; + border-color: rgb(125 211 252 / var(--tw-border-opacity)); +} + +.hover\:border-indigo-300:hover { + --tw-border-opacity: 1; + border-color: rgb(165 180 252 / var(--tw-border-opacity)); +} + +.hover\:bg-pink-200:hover { --tw-bg-opacity: 1; - background-color: rgb(245 245 244 / var(--tw-bg-opacity)); + background-color: rgb(251 207 232 / var(--tw-bg-opacity)); } -.prose-h1\:mb-0 :is(:where(h1):not(:where([class~="not-prose"] *))) { - margin-bottom: 0px; +.hover\:bg-rose-200:hover { + --tw-bg-opacity: 1; + background-color: rgb(254 205 211 / var(--tw-bg-opacity)); } -.prose-h1\:font-light :is(:where(h1):not(:where([class~="not-prose"] *))) { - font-weight: 300; +.hover\:bg-sky-200:hover { + --tw-bg-opacity: 1; + background-color: rgb(186 230 253 / var(--tw-bg-opacity)); } -.prose-h2\:my-0 :is(:where(h2):not(:where([class~="not-prose"] *))) { - margin-top: 0px; - margin-bottom: 0px; +.hover\:bg-indigo-200:hover { + --tw-bg-opacity: 1; + background-color: rgb(199 210 254 / var(--tw-bg-opacity)); +} + +.prose-h2\:text-center :is(:where(h2):not(:where([class~="not-prose"] *))) { + text-align: center; +} + +.prose-h2\:text-3xl :is(:where(h2):not(:where([class~="not-prose"] *))) { + font-size: 1.875rem; + line-height: 2.25rem; +} + +.prose-h2\:text-2xl :is(:where(h2):not(:where([class~="not-prose"] *))) { + font-size: 1.5rem; + line-height: 2rem; +} + +.prose-h2\:font-normal :is(:where(h2):not(:where([class~="not-prose"] *))) { + font-weight: 400; } .prose-h2\:font-light :is(:where(h2):not(:where([class~="not-prose"] *))) { font-weight: 300; } -.prose-h3\:text-xs :is(:where(h3):not(:where([class~="not-prose"] *))) { - font-size: .75rem; +.prose-h3\:font-normal :is(:where(h3):not(:where([class~="not-prose"] *))) { + font-weight: 400; +} + +.prose-h4\:text-center :is(:where(h4):not(:where([class~="not-prose"] *))) { + text-align: center; +} + +.prose-h4\:text-xl :is(:where(h4):not(:where([class~="not-prose"] *))) { + font-size: 1.25rem; + line-height: 1.75rem; +} + +.prose-h4\:font-normal :is(:where(h4):not(:where([class~="not-prose"] *))) { + font-weight: 400; } @media (min-width: 1024px) { - .lg\:grid-cols-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - .lg\:flex-row { flex-direction: row; } + .lg\:flex-row-reverse { + flex-direction: row-reverse; + } + .lg\:items-start { align-items: flex-start; } @@ -1563,4 +1845,8 @@ select { .lg\:items-end { align-items: flex-end; } + + .lg\:text-right { + text-align: right; + } } diff --git a/theme/static_src/src/styles.css b/theme/static_src/src/styles.css index 05d2292..5eeda30 100644 --- a/theme/static_src/src/styles.css +++ b/theme/static_src/src/styles.css @@ -4,13 +4,23 @@ @layer components { .nav-item > a { - @apply inline-block px-2 pt-[10px] hover:pt-[7px] pb-2 - bg-emerald-100 hover:bg-emerald-200 shadow-md - border border-emerald-200 hover:border-emerald-300 border-t-emerald-500 hover:border-t-emerald-600 hover:border-t-4; + @apply rounded-md transition ease-in-out duration-300 inline-block px-2 pb-[10px] hover:pb-[7px] pt-2 + bg-green-100 hover:bg-green-200 shadow-md + border border-green-200 hover:border-green-300 border-b-green-500 hover:border-b-green-600 hover:border-b-4; } .active > a { - @apply bg-emerald-300 border-emerald-300 border-t-4 border-t-emerald-600 pt-[7px]; + @apply bg-green-300 border-green-300 border-b-4 border-b-green-600 pb-[7px]; + } + + .adm_nav-item > a { + @apply rounded-md transition ease-in-out duration-300 inline-block px-2 pb-[10px] hover:pb-[7px] pt-2 + bg-blue-100 hover:bg-blue-200 shadow-md + border border-blue-200 hover:border-blue-300 border-b-blue-500 hover:border-b-blue-600 hover:border-b-4; + } + + .adm_active > a { + @apply bg-blue-300 border-blue-300 border-b-4 border-b-blue-600 pb-[7px]; } } diff --git a/theme/static_src/tailwind.config.js b/theme/static_src/tailwind.config.js index 81c7aa1..84505e8 100644 --- a/theme/static_src/tailwind.config.js +++ b/theme/static_src/tailwind.config.js @@ -18,13 +18,13 @@ module.exports = { * Main templates directory of the project (BASE_DIR/templates). * Adjust the following line to match your project structure. */ - "../../templates/**/*.html", + "../../../templates/**/*.html", /* * Templates in other django apps (BASE_DIR//templates). * Adjust the following line to match your project structure. */ - "../../**/templates/**/*.html", + "../../../**/templates/**/*.html", /** * JS: If you use Tailwind CSS in JavaScript, uncomment the following lines and make sure @@ -42,20 +42,6 @@ module.exports = { // '../../**/*.py' ], theme: { - fontSize: { - xs: ".75rem", - sm: ".875rem", - tiny: ".875rem", - base: "1rem", - lg: "1.125rem", - xl: "1.25rem", - "2xl": "1.5rem", - "3xl": "1.875rem", - "4xl": "2.25rem", - "5xl": "3rem", - "6xl": "4rem", - "7xl": "5rem", - }, extend: {}, }, plugins: [