first implementation of new layout
This commit is contained in:
@@ -107,7 +107,7 @@ def profile_view(request, member_id=None):
|
||||
logger.info("Wrong member id '{}'".format(member_id))
|
||||
raise Http404("no member")
|
||||
|
||||
jobs = deque(JobMember.members.filter(member__id=member_id))
|
||||
jobs = deque(JobMember.members.filter(member__id=member_id).order_by("job_start"))
|
||||
|
||||
context = {
|
||||
"pinned_job_groups": pinned_job_groups,
|
||||
|
||||
2517
fet2020/static/js/alpinejs@3.2.2.js
Normal file
2517
fet2020/static/js/alpinejs@3.2.2.js
Normal file
File diff suppressed because it is too large
Load Diff
484
fet2020/static/js/gumshoe@5.1.1.js
Normal file
484
fet2020/static/js/gumshoe@5.1.1.js
Normal file
@@ -0,0 +1,484 @@
|
||||
/*!
|
||||
* gumshoejs v5.1.1
|
||||
* A simple, framework-agnostic scrollspy script.
|
||||
* (c) 2019 Chris Ferdinandi
|
||||
* MIT License
|
||||
* http://github.com/cferdinandi/gumshoe
|
||||
*/
|
||||
|
||||
(function (root, factory) {
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
define([], (function () {
|
||||
return factory(root);
|
||||
}));
|
||||
} else if ( typeof exports === 'object' ) {
|
||||
module.exports = factory(root);
|
||||
} else {
|
||||
root.Gumshoe = factory(root);
|
||||
}
|
||||
})(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this, (function (window) {
|
||||
|
||||
'use strict';
|
||||
|
||||
//
|
||||
// Defaults
|
||||
//
|
||||
|
||||
var defaults = {
|
||||
|
||||
// Active classes
|
||||
navClass: 'active',
|
||||
contentClass: 'active',
|
||||
|
||||
// Nested navigation
|
||||
nested: false,
|
||||
nestedClass: 'active',
|
||||
|
||||
// Offset & reflow
|
||||
offset: 0,
|
||||
reflow: false,
|
||||
|
||||
// Event support
|
||||
events: true
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Merge two or more objects together.
|
||||
* @param {Object} objects The objects to merge together
|
||||
* @returns {Object} Merged values of defaults and options
|
||||
*/
|
||||
var extend = function () {
|
||||
var merged = {};
|
||||
Array.prototype.forEach.call(arguments, (function (obj) {
|
||||
for (var key in obj) {
|
||||
if (!obj.hasOwnProperty(key)) return;
|
||||
merged[key] = obj[key];
|
||||
}
|
||||
}));
|
||||
return merged;
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit a custom event
|
||||
* @param {String} type The event type
|
||||
* @param {Node} elem The element to attach the event to
|
||||
* @param {Object} detail Any details to pass along with the event
|
||||
*/
|
||||
var emitEvent = function (type, elem, detail) {
|
||||
|
||||
// Make sure events are enabled
|
||||
if (!detail.settings.events) return;
|
||||
|
||||
// Create a new event
|
||||
var event = new CustomEvent(type, {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
detail: detail
|
||||
});
|
||||
|
||||
// Dispatch the event
|
||||
elem.dispatchEvent(event);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an element's distance from the top of the Document.
|
||||
* @param {Node} elem The element
|
||||
* @return {Number} Distance from the top in pixels
|
||||
*/
|
||||
var getOffsetTop = function (elem) {
|
||||
var location = 0;
|
||||
if (elem.offsetParent) {
|
||||
while (elem) {
|
||||
location += elem.offsetTop;
|
||||
elem = elem.offsetParent;
|
||||
}
|
||||
}
|
||||
return location >= 0 ? location : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sort content from first to last in the DOM
|
||||
* @param {Array} contents The content areas
|
||||
*/
|
||||
var sortContents = function (contents) {
|
||||
if(contents) {
|
||||
contents.sort((function (item1, item2) {
|
||||
var offset1 = getOffsetTop(item1.content);
|
||||
var offset2 = getOffsetTop(item2.content);
|
||||
if (offset1 < offset2) return -1;
|
||||
return 1;
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the offset to use for calculating position
|
||||
* @param {Object} settings The settings for this instantiation
|
||||
* @return {Float} The number of pixels to offset the calculations
|
||||
*/
|
||||
var getOffset = function (settings) {
|
||||
|
||||
// if the offset is a function run it
|
||||
if (typeof settings.offset === 'function') {
|
||||
return parseFloat(settings.offset());
|
||||
}
|
||||
|
||||
// Otherwise, return it as-is
|
||||
return parseFloat(settings.offset);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the document element's height
|
||||
* @private
|
||||
* @returns {Number}
|
||||
*/
|
||||
var getDocumentHeight = function () {
|
||||
return Math.max(
|
||||
document.body.scrollHeight, document.documentElement.scrollHeight,
|
||||
document.body.offsetHeight, document.documentElement.offsetHeight,
|
||||
document.body.clientHeight, document.documentElement.clientHeight
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine if an element is in view
|
||||
* @param {Node} elem The element
|
||||
* @param {Object} settings The settings for this instantiation
|
||||
* @param {Boolean} bottom If true, check if element is above bottom of viewport instead
|
||||
* @return {Boolean} Returns true if element is in the viewport
|
||||
*/
|
||||
var isInView = function (elem, settings, bottom) {
|
||||
var bounds = elem.getBoundingClientRect();
|
||||
var offset = getOffset(settings);
|
||||
if (bottom) {
|
||||
return parseInt(bounds.bottom, 10) < (window.innerHeight || document.documentElement.clientHeight);
|
||||
}
|
||||
return parseInt(bounds.top, 10) <= offset;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if at the bottom of the viewport
|
||||
* @return {Boolean} If true, page is at the bottom of the viewport
|
||||
*/
|
||||
var isAtBottom = function () {
|
||||
if (window.innerHeight + window.pageYOffset >= getDocumentHeight()) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the last item should be used (even if not at the top of the page)
|
||||
* @param {Object} item The last item
|
||||
* @param {Object} settings The settings for this instantiation
|
||||
* @return {Boolean} If true, use the last item
|
||||
*/
|
||||
var useLastItem = function (item, settings) {
|
||||
if (isAtBottom() && isInView(item.content, settings, true)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the active content
|
||||
* @param {Array} contents The content areas
|
||||
* @param {Object} settings The settings for this instantiation
|
||||
* @return {Object} The content area and matching navigation link
|
||||
*/
|
||||
var getActive = function (contents, settings) {
|
||||
var last = contents[contents.length-1];
|
||||
if (useLastItem(last, settings)) return last;
|
||||
for (var i = contents.length - 1; i >= 0; i--) {
|
||||
if (isInView(contents[i].content, settings)) return contents[i];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deactivate parent navs in a nested navigation
|
||||
* @param {Node} nav The starting navigation element
|
||||
* @param {Object} settings The settings for this instantiation
|
||||
*/
|
||||
var deactivateNested = function (nav, settings) {
|
||||
|
||||
// If nesting isn't activated, bail
|
||||
if (!settings.nested) return;
|
||||
|
||||
// Get the parent navigation
|
||||
var li = nav.parentNode.closest('li');
|
||||
if (!li) return;
|
||||
|
||||
// Remove the active class
|
||||
li.classList.remove(settings.nestedClass);
|
||||
|
||||
// Apply recursively to any parent navigation elements
|
||||
deactivateNested(li, settings);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Deactivate a nav and content area
|
||||
* @param {Object} items The nav item and content to deactivate
|
||||
* @param {Object} settings The settings for this instantiation
|
||||
*/
|
||||
var deactivate = function (items, settings) {
|
||||
|
||||
// Make sure their are items to deactivate
|
||||
if (!items) return;
|
||||
|
||||
// Get the parent list item
|
||||
var li = items.nav.closest('li');
|
||||
if (!li) return;
|
||||
|
||||
// Remove the active class from the nav and content
|
||||
li.classList.remove(settings.navClass);
|
||||
items.content.classList.remove(settings.contentClass);
|
||||
|
||||
// Deactivate any parent navs in a nested navigation
|
||||
deactivateNested(li, settings);
|
||||
|
||||
// Emit a custom event
|
||||
emitEvent('gumshoeDeactivate', li, {
|
||||
link: items.nav,
|
||||
content: items.content,
|
||||
settings: settings
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Activate parent navs in a nested navigation
|
||||
* @param {Node} nav The starting navigation element
|
||||
* @param {Object} settings The settings for this instantiation
|
||||
*/
|
||||
var activateNested = function (nav, settings) {
|
||||
|
||||
// If nesting isn't activated, bail
|
||||
if (!settings.nested) return;
|
||||
|
||||
// Get the parent navigation
|
||||
var li = nav.parentNode.closest('li');
|
||||
if (!li) return;
|
||||
|
||||
// Add the active class
|
||||
li.classList.add(settings.nestedClass);
|
||||
|
||||
// Apply recursively to any parent navigation elements
|
||||
activateNested(li, settings);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Activate a nav and content area
|
||||
* @param {Object} items The nav item and content to activate
|
||||
* @param {Object} settings The settings for this instantiation
|
||||
*/
|
||||
var activate = function (items, settings) {
|
||||
|
||||
// Make sure their are items to activate
|
||||
if (!items) return;
|
||||
|
||||
// Get the parent list item
|
||||
var li = items.nav.closest('li');
|
||||
if (!li) return;
|
||||
|
||||
// Add the active class to the nav and content
|
||||
li.classList.add(settings.navClass);
|
||||
items.content.classList.add(settings.contentClass);
|
||||
|
||||
// Activate any parent navs in a nested navigation
|
||||
activateNested(li, settings);
|
||||
|
||||
// Emit a custom event
|
||||
emitEvent('gumshoeActivate', li, {
|
||||
link: items.nav,
|
||||
content: items.content,
|
||||
settings: settings
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the Constructor object
|
||||
* @param {String} selector The selector to use for navigation items
|
||||
* @param {Object} options User options and settings
|
||||
*/
|
||||
var Constructor = function (selector, options) {
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
|
||||
var publicAPIs = {};
|
||||
var navItems, contents, current, timeout, settings;
|
||||
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Set variables from DOM elements
|
||||
*/
|
||||
publicAPIs.setup = function () {
|
||||
|
||||
// Get all nav items
|
||||
navItems = document.querySelectorAll(selector);
|
||||
|
||||
// Create contents array
|
||||
contents = [];
|
||||
|
||||
// Loop through each item, get it's matching content, and push to the array
|
||||
Array.prototype.forEach.call(navItems, (function (item) {
|
||||
|
||||
// Get the content for the nav item
|
||||
var content = document.getElementById(decodeURIComponent(item.hash.substr(1)));
|
||||
if (!content) return;
|
||||
|
||||
// Push to the contents array
|
||||
contents.push({
|
||||
nav: item,
|
||||
content: content
|
||||
});
|
||||
|
||||
}));
|
||||
|
||||
// Sort contents by the order they appear in the DOM
|
||||
sortContents(contents);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Detect which content is currently active
|
||||
*/
|
||||
publicAPIs.detect = function () {
|
||||
|
||||
// Get the active content
|
||||
var active = getActive(contents, settings);
|
||||
|
||||
// if there's no active content, deactivate and bail
|
||||
if (!active) {
|
||||
if (current) {
|
||||
deactivate(current, settings);
|
||||
current = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If the active content is the one currently active, do nothing
|
||||
if (current && active.content === current.content) return;
|
||||
|
||||
// Deactivate the current content and activate the new content
|
||||
deactivate(current, settings);
|
||||
activate(active, settings);
|
||||
|
||||
// Update the currently active content
|
||||
current = active;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Detect the active content on scroll
|
||||
* Debounced for performance
|
||||
*/
|
||||
var scrollHandler = function (event) {
|
||||
|
||||
// If there's a timer, cancel it
|
||||
if (timeout) {
|
||||
window.cancelAnimationFrame(timeout);
|
||||
}
|
||||
|
||||
// Setup debounce callback
|
||||
timeout = window.requestAnimationFrame(publicAPIs.detect);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Update content sorting on resize
|
||||
* Debounced for performance
|
||||
*/
|
||||
var resizeHandler = function (event) {
|
||||
|
||||
// If there's a timer, cancel it
|
||||
if (timeout) {
|
||||
window.cancelAnimationFrame(timeout);
|
||||
}
|
||||
|
||||
// Setup debounce callback
|
||||
timeout = window.requestAnimationFrame((function () {
|
||||
sortContents(contents);
|
||||
publicAPIs.detect();
|
||||
}));
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy the current instantiation
|
||||
*/
|
||||
publicAPIs.destroy = function () {
|
||||
|
||||
// Undo DOM changes
|
||||
if (current) {
|
||||
deactivate(current, settings);
|
||||
}
|
||||
|
||||
// Remove event listeners
|
||||
window.removeEventListener('scroll', scrollHandler, false);
|
||||
if (settings.reflow) {
|
||||
window.removeEventListener('resize', resizeHandler, false);
|
||||
}
|
||||
|
||||
// Reset variables
|
||||
contents = null;
|
||||
navItems = null;
|
||||
current = null;
|
||||
timeout = null;
|
||||
settings = null;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the current instantiation
|
||||
*/
|
||||
var init = function () {
|
||||
|
||||
// Merge user options into defaults
|
||||
settings = extend(defaults, options || {});
|
||||
|
||||
// Setup variables based on the current DOM
|
||||
publicAPIs.setup();
|
||||
|
||||
// Find the currently active content
|
||||
publicAPIs.detect();
|
||||
|
||||
// Setup event listeners
|
||||
window.addEventListener('scroll', scrollHandler, false);
|
||||
if (settings.reflow) {
|
||||
window.addEventListener('resize', resizeHandler, false);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Initialize and return the public APIs
|
||||
//
|
||||
|
||||
init();
|
||||
return publicAPIs;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Return the Constructor
|
||||
//
|
||||
|
||||
return Constructor;
|
||||
|
||||
}));
|
||||
36
fet2020/static/js/scripts.js
Normal file
36
fet2020/static/js/scripts.js
Normal file
@@ -0,0 +1,36 @@
|
||||
// Open article on click without an anchor-tag.
|
||||
function openArticle(link){
|
||||
window.location.href=link;
|
||||
}
|
||||
|
||||
if(cookieSet("InfoBoxHidden")){
|
||||
let element = document.getElementById("infoBox");
|
||||
element.classList.toggle("hidden");
|
||||
}
|
||||
|
||||
function hideInfoBox(){
|
||||
let element = document.getElementById("infoBox");
|
||||
element.classList.toggle("hidden");
|
||||
|
||||
let exMinutes = 2; // Gültigkeit des Cookies in Tagen
|
||||
const d = new Date();
|
||||
d.setTime(d.getTime() + (exMinutes*60*1000));
|
||||
let expires = "expires="+ d.toUTCString();
|
||||
document.cookie = "InfoBoxHidden=true; expires=" + expires + ";path=/;SameSite=Strict";
|
||||
}
|
||||
|
||||
function cookieSet(cname) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for(let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
650
fet2020/static/js/smooth-scroll@16.1.2.js
Normal file
650
fet2020/static/js/smooth-scroll@16.1.2.js
Normal file
@@ -0,0 +1,650 @@
|
||||
/*!
|
||||
* smooth-scroll v16.1.2
|
||||
* Animate scrolling to anchor links
|
||||
* (c) 2020 Chris Ferdinandi
|
||||
* MIT License
|
||||
* http://github.com/cferdinandi/smooth-scroll
|
||||
*/
|
||||
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([], (function () {
|
||||
return factory(root);
|
||||
}));
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory(root);
|
||||
} else {
|
||||
root.SmoothScroll = factory(root);
|
||||
}
|
||||
})(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this, (function (window) {
|
||||
|
||||
'use strict';
|
||||
|
||||
//
|
||||
// Default settings
|
||||
//
|
||||
|
||||
var defaults = {
|
||||
|
||||
// Selectors
|
||||
ignore: '[data-scroll-ignore]',
|
||||
header: null,
|
||||
topOnEmptyHash: true,
|
||||
|
||||
// Speed & Duration
|
||||
speed: 500,
|
||||
speedAsDuration: false,
|
||||
durationMax: null,
|
||||
durationMin: null,
|
||||
clip: true,
|
||||
offset: 0,
|
||||
|
||||
// Easing
|
||||
easing: 'easeInOutCubic',
|
||||
customEasing: null,
|
||||
|
||||
// History
|
||||
updateURL: true,
|
||||
popstate: true,
|
||||
|
||||
// Custom Events
|
||||
emitEvents: true
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Utility Methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Check if browser supports required methods
|
||||
* @return {Boolean} Returns true if all required methods are supported
|
||||
*/
|
||||
var supports = function () {
|
||||
return (
|
||||
'querySelector' in document &&
|
||||
'addEventListener' in window &&
|
||||
'requestAnimationFrame' in window &&
|
||||
'closest' in window.Element.prototype
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Merge two or more objects together.
|
||||
* @param {Object} objects The objects to merge together
|
||||
* @returns {Object} Merged values of defaults and options
|
||||
*/
|
||||
var extend = function () {
|
||||
var merged = {};
|
||||
Array.prototype.forEach.call(arguments, (function (obj) {
|
||||
for (var key in obj) {
|
||||
if (!obj.hasOwnProperty(key)) return;
|
||||
merged[key] = obj[key];
|
||||
}
|
||||
}));
|
||||
return merged;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check to see if user prefers reduced motion
|
||||
* @param {Object} settings Script settings
|
||||
*/
|
||||
var reduceMotion = function () {
|
||||
if ('matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the height of an element.
|
||||
* @param {Node} elem The element to get the height of
|
||||
* @return {Number} The element's height in pixels
|
||||
*/
|
||||
var getHeight = function (elem) {
|
||||
return parseInt(window.getComputedStyle(elem).height, 10);
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape special characters for use with querySelector
|
||||
* @author Mathias Bynens
|
||||
* @link https://github.com/mathiasbynens/CSS.escape
|
||||
* @param {String} id The anchor ID to escape
|
||||
*/
|
||||
var escapeCharacters = function (id) {
|
||||
|
||||
// Remove leading hash
|
||||
if (id.charAt(0) === '#') {
|
||||
id = id.substr(1);
|
||||
}
|
||||
|
||||
var string = String(id);
|
||||
var length = string.length;
|
||||
var index = -1;
|
||||
var codeUnit;
|
||||
var result = '';
|
||||
var firstCodeUnit = string.charCodeAt(0);
|
||||
while (++index < length) {
|
||||
codeUnit = string.charCodeAt(index);
|
||||
// Note: there’s no need to special-case astral symbols, surrogate
|
||||
// pairs, or lone surrogates.
|
||||
|
||||
// If the character is NULL (U+0000), then throw an
|
||||
// `InvalidCharacterError` exception and terminate these steps.
|
||||
if (codeUnit === 0x0000) {
|
||||
throw new InvalidCharacterError(
|
||||
'Invalid character: the input contains U+0000.'
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
// If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
|
||||
// U+007F, […]
|
||||
(codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
|
||||
// If the character is the first character and is in the range [0-9]
|
||||
// (U+0030 to U+0039), […]
|
||||
(index === 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
|
||||
// If the character is the second character and is in the range [0-9]
|
||||
// (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
|
||||
(
|
||||
index === 1 &&
|
||||
codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
|
||||
firstCodeUnit === 0x002D
|
||||
)
|
||||
) {
|
||||
// http://dev.w3.org/csswg/cssom/#escape-a-character-as-code-point
|
||||
result += '\\' + codeUnit.toString(16) + ' ';
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the character is not handled by one of the above rules and is
|
||||
// greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
|
||||
// is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
|
||||
// U+005A), or [a-z] (U+0061 to U+007A), […]
|
||||
if (
|
||||
codeUnit >= 0x0080 ||
|
||||
codeUnit === 0x002D ||
|
||||
codeUnit === 0x005F ||
|
||||
codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
|
||||
codeUnit >= 0x0041 && codeUnit <= 0x005A ||
|
||||
codeUnit >= 0x0061 && codeUnit <= 0x007A
|
||||
) {
|
||||
// the character itself
|
||||
result += string.charAt(index);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, the escaped character.
|
||||
// http://dev.w3.org/csswg/cssom/#escape-a-character
|
||||
result += '\\' + string.charAt(index);
|
||||
|
||||
}
|
||||
|
||||
// Return sanitized hash
|
||||
return '#' + result;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the easing pattern
|
||||
* @link https://gist.github.com/gre/1650294
|
||||
* @param {String} type Easing pattern
|
||||
* @param {Number} time Time animation should take to complete
|
||||
* @returns {Number}
|
||||
*/
|
||||
var easingPattern = function (settings, time) {
|
||||
var pattern;
|
||||
|
||||
// Default Easing Patterns
|
||||
if (settings.easing === 'easeInQuad') pattern = time * time; // accelerating from zero velocity
|
||||
if (settings.easing === 'easeOutQuad') pattern = time * (2 - time); // decelerating to zero velocity
|
||||
if (settings.easing === 'easeInOutQuad') pattern = time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time; // acceleration until halfway, then deceleration
|
||||
if (settings.easing === 'easeInCubic') pattern = time * time * time; // accelerating from zero velocity
|
||||
if (settings.easing === 'easeOutCubic') pattern = (--time) * time * time + 1; // decelerating to zero velocity
|
||||
if (settings.easing === 'easeInOutCubic') pattern = time < 0.5 ? 4 * time * time * time : (time - 1) * (2 * time - 2) * (2 * time - 2) + 1; // acceleration until halfway, then deceleration
|
||||
if (settings.easing === 'easeInQuart') pattern = time * time * time * time; // accelerating from zero velocity
|
||||
if (settings.easing === 'easeOutQuart') pattern = 1 - (--time) * time * time * time; // decelerating to zero velocity
|
||||
if (settings.easing === 'easeInOutQuart') pattern = time < 0.5 ? 8 * time * time * time * time : 1 - 8 * (--time) * time * time * time; // acceleration until halfway, then deceleration
|
||||
if (settings.easing === 'easeInQuint') pattern = time * time * time * time * time; // accelerating from zero velocity
|
||||
if (settings.easing === 'easeOutQuint') pattern = 1 + (--time) * time * time * time * time; // decelerating to zero velocity
|
||||
if (settings.easing === 'easeInOutQuint') pattern = time < 0.5 ? 16 * time * time * time * time * time : 1 + 16 * (--time) * time * time * time * time; // acceleration until halfway, then deceleration
|
||||
|
||||
// Custom Easing Patterns
|
||||
if (!!settings.customEasing) pattern = settings.customEasing(time);
|
||||
|
||||
return pattern || time; // no easing, no acceleration
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine the document's height
|
||||
* @returns {Number}
|
||||
*/
|
||||
var getDocumentHeight = function () {
|
||||
return Math.max(
|
||||
document.body.scrollHeight, document.documentElement.scrollHeight,
|
||||
document.body.offsetHeight, document.documentElement.offsetHeight,
|
||||
document.body.clientHeight, document.documentElement.clientHeight
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate how far to scroll
|
||||
* Clip support added by robjtede - https://github.com/cferdinandi/smooth-scroll/issues/405
|
||||
* @param {Element} anchor The anchor element to scroll to
|
||||
* @param {Number} headerHeight Height of a fixed header, if any
|
||||
* @param {Number} offset Number of pixels by which to offset scroll
|
||||
* @param {Boolean} clip If true, adjust scroll distance to prevent abrupt stops near the bottom of the page
|
||||
* @returns {Number}
|
||||
*/
|
||||
var getEndLocation = function (anchor, headerHeight, offset, clip) {
|
||||
var location = 0;
|
||||
if (anchor.offsetParent) {
|
||||
do {
|
||||
location += anchor.offsetTop;
|
||||
anchor = anchor.offsetParent;
|
||||
} while (anchor);
|
||||
}
|
||||
location = Math.max(location - headerHeight - offset, 0);
|
||||
if (clip) {
|
||||
location = Math.min(location, getDocumentHeight() - window.innerHeight);
|
||||
}
|
||||
return location;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the height of the fixed header
|
||||
* @param {Node} header The header
|
||||
* @return {Number} The height of the header
|
||||
*/
|
||||
var getHeaderHeight = function (header) {
|
||||
return !header ? 0 : (getHeight(header) + header.offsetTop);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the speed to use for the animation
|
||||
* @param {Number} distance The distance to travel
|
||||
* @param {Object} settings The plugin settings
|
||||
* @return {Number} How fast to animate
|
||||
*/
|
||||
var getSpeed = function (distance, settings) {
|
||||
var speed = settings.speedAsDuration ? settings.speed : Math.abs(distance / 1000 * settings.speed);
|
||||
if (settings.durationMax && speed > settings.durationMax) return settings.durationMax;
|
||||
if (settings.durationMin && speed < settings.durationMin) return settings.durationMin;
|
||||
return parseInt(speed, 10);
|
||||
};
|
||||
|
||||
var setHistory = function (options) {
|
||||
|
||||
// Make sure this should run
|
||||
if (!history.replaceState || !options.updateURL || history.state) return;
|
||||
|
||||
// Get the hash to use
|
||||
var hash = window.location.hash;
|
||||
hash = hash ? hash : '';
|
||||
|
||||
// Set a default history
|
||||
history.replaceState(
|
||||
{
|
||||
smoothScroll: JSON.stringify(options),
|
||||
anchor: hash ? hash : window.pageYOffset
|
||||
},
|
||||
document.title,
|
||||
hash ? hash : window.location.href
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the URL
|
||||
* @param {Node} anchor The anchor that was scrolled to
|
||||
* @param {Boolean} isNum If true, anchor is a number
|
||||
* @param {Object} options Settings for Smooth Scroll
|
||||
*/
|
||||
var updateURL = function (anchor, isNum, options) {
|
||||
|
||||
// Bail if the anchor is a number
|
||||
if (isNum) return;
|
||||
|
||||
// Verify that pushState is supported and the updateURL option is enabled
|
||||
if (!history.pushState || !options.updateURL) return;
|
||||
|
||||
// Update URL
|
||||
history.pushState(
|
||||
{
|
||||
smoothScroll: JSON.stringify(options),
|
||||
anchor: anchor.id
|
||||
},
|
||||
document.title,
|
||||
anchor === document.documentElement ? '#top' : '#' + anchor.id
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Bring the anchored element into focus
|
||||
* @param {Node} anchor The anchor element
|
||||
* @param {Number} endLocation The end location to scroll to
|
||||
* @param {Boolean} isNum If true, scroll is to a position rather than an element
|
||||
*/
|
||||
var adjustFocus = function (anchor, endLocation, isNum) {
|
||||
|
||||
// Is scrolling to top of page, blur
|
||||
if (anchor === 0) {
|
||||
document.body.focus();
|
||||
}
|
||||
|
||||
// Don't run if scrolling to a number on the page
|
||||
if (isNum) return;
|
||||
|
||||
// Otherwise, bring anchor element into focus
|
||||
anchor.focus();
|
||||
if (document.activeElement !== anchor) {
|
||||
anchor.setAttribute('tabindex', '-1');
|
||||
anchor.focus();
|
||||
anchor.style.outline = 'none';
|
||||
}
|
||||
window.scrollTo(0 , endLocation);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit a custom event
|
||||
* @param {String} type The event type
|
||||
* @param {Object} options The settings object
|
||||
* @param {Node} anchor The anchor element
|
||||
* @param {Node} toggle The toggle element
|
||||
*/
|
||||
var emitEvent = function (type, options, anchor, toggle) {
|
||||
if (!options.emitEvents || typeof window.CustomEvent !== 'function') return;
|
||||
var event = new CustomEvent(type, {
|
||||
bubbles: true,
|
||||
detail: {
|
||||
anchor: anchor,
|
||||
toggle: toggle
|
||||
}
|
||||
});
|
||||
document.dispatchEvent(event);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// SmoothScroll Constructor
|
||||
//
|
||||
|
||||
var SmoothScroll = function (selector, options) {
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
|
||||
var smoothScroll = {}; // Object for public APIs
|
||||
var settings, anchor, toggle, fixedHeader, eventTimeout, animationInterval;
|
||||
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Cancel a scroll-in-progress
|
||||
*/
|
||||
smoothScroll.cancelScroll = function (noEvent) {
|
||||
cancelAnimationFrame(animationInterval);
|
||||
animationInterval = null;
|
||||
if (noEvent) return;
|
||||
emitEvent('scrollCancel', settings);
|
||||
};
|
||||
|
||||
/**
|
||||
* Start/stop the scrolling animation
|
||||
* @param {Node|Number} anchor The element or position to scroll to
|
||||
* @param {Element} toggle The element that toggled the scroll event
|
||||
* @param {Object} options
|
||||
*/
|
||||
smoothScroll.animateScroll = function (anchor, toggle, options) {
|
||||
|
||||
// Cancel any in progress scrolls
|
||||
smoothScroll.cancelScroll();
|
||||
|
||||
// Local settings
|
||||
var _settings = extend(settings || defaults, options || {}); // Merge user options with defaults
|
||||
|
||||
// Selectors and variables
|
||||
var isNum = Object.prototype.toString.call(anchor) === '[object Number]' ? true : false;
|
||||
var anchorElem = isNum || !anchor.tagName ? null : anchor;
|
||||
if (!isNum && !anchorElem) return;
|
||||
var startLocation = window.pageYOffset; // Current location on the page
|
||||
if (_settings.header && !fixedHeader) {
|
||||
// Get the fixed header if not already set
|
||||
fixedHeader = document.querySelector(_settings.header);
|
||||
}
|
||||
var headerHeight = getHeaderHeight(fixedHeader);
|
||||
var endLocation = isNum ? anchor : getEndLocation(anchorElem, headerHeight, parseInt((typeof _settings.offset === 'function' ? _settings.offset(anchor, toggle) : _settings.offset), 10), _settings.clip); // Location to scroll to
|
||||
var distance = endLocation - startLocation; // distance to travel
|
||||
var documentHeight = getDocumentHeight();
|
||||
var timeLapsed = 0;
|
||||
var speed = getSpeed(distance, _settings);
|
||||
var start, percentage, position;
|
||||
|
||||
/**
|
||||
* Stop the scroll animation when it reaches its target (or the bottom/top of page)
|
||||
* @param {Number} position Current position on the page
|
||||
* @param {Number} endLocation Scroll to location
|
||||
* @param {Number} animationInterval How much to scroll on this loop
|
||||
*/
|
||||
var stopAnimateScroll = function (position, endLocation) {
|
||||
|
||||
// Get the current location
|
||||
var currentLocation = window.pageYOffset;
|
||||
|
||||
// Check if the end location has been reached yet (or we've hit the end of the document)
|
||||
if (position == endLocation || currentLocation == endLocation || ((startLocation < endLocation && window.innerHeight + currentLocation) >= documentHeight)) {
|
||||
|
||||
// Clear the animation timer
|
||||
smoothScroll.cancelScroll(true);
|
||||
|
||||
// Bring the anchored element into focus
|
||||
adjustFocus(anchor, endLocation, isNum);
|
||||
|
||||
// Emit a custom event
|
||||
emitEvent('scrollStop', _settings, anchor, toggle);
|
||||
|
||||
// Reset start
|
||||
start = null;
|
||||
animationInterval = null;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Loop scrolling animation
|
||||
*/
|
||||
var loopAnimateScroll = function (timestamp) {
|
||||
if (!start) { start = timestamp; }
|
||||
timeLapsed += timestamp - start;
|
||||
percentage = speed === 0 ? 0 : (timeLapsed / speed);
|
||||
percentage = (percentage > 1) ? 1 : percentage;
|
||||
position = startLocation + (distance * easingPattern(_settings, percentage));
|
||||
window.scrollTo(0, Math.floor(position));
|
||||
if (!stopAnimateScroll(position, endLocation)) {
|
||||
animationInterval = window.requestAnimationFrame(loopAnimateScroll);
|
||||
start = timestamp;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset position to fix weird iOS bug
|
||||
* @link https://github.com/cferdinandi/smooth-scroll/issues/45
|
||||
*/
|
||||
if (window.pageYOffset === 0) {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
// Update the URL
|
||||
updateURL(anchor, isNum, _settings);
|
||||
|
||||
// If the user prefers reduced motion, jump to location
|
||||
if (reduceMotion()) {
|
||||
window.scrollTo(0, Math.floor(endLocation));
|
||||
return;
|
||||
}
|
||||
|
||||
// Emit a custom event
|
||||
emitEvent('scrollStart', _settings, anchor, toggle);
|
||||
|
||||
// Start scrolling animation
|
||||
smoothScroll.cancelScroll(true);
|
||||
window.requestAnimationFrame(loopAnimateScroll);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* If smooth scroll element clicked, animate scroll
|
||||
*/
|
||||
var clickHandler = function (event) {
|
||||
|
||||
// Don't run if event was canceled but still bubbled up
|
||||
// By @mgreter - https://github.com/cferdinandi/smooth-scroll/pull/462/
|
||||
if (event.defaultPrevented) return;
|
||||
|
||||
// Don't run if right-click or command/control + click or shift + click
|
||||
if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey) return;
|
||||
|
||||
// Check if event.target has closest() method
|
||||
// By @totegi - https://github.com/cferdinandi/smooth-scroll/pull/401/
|
||||
if (!('closest' in event.target)) return;
|
||||
|
||||
// Check if a smooth scroll link was clicked
|
||||
toggle = event.target.closest(selector);
|
||||
if (!toggle || toggle.tagName.toLowerCase() !== 'a' || event.target.closest(settings.ignore)) return;
|
||||
|
||||
// Only run if link is an anchor and points to the current page
|
||||
if (toggle.hostname !== window.location.hostname || toggle.pathname !== window.location.pathname || !/#/.test(toggle.href)) return;
|
||||
|
||||
// Get an escaped version of the hash
|
||||
var hash;
|
||||
try {
|
||||
hash = escapeCharacters(decodeURIComponent(toggle.hash));
|
||||
} catch(e) {
|
||||
hash = escapeCharacters(toggle.hash);
|
||||
}
|
||||
|
||||
// Get the anchored element
|
||||
var anchor;
|
||||
if (hash === '#') {
|
||||
if (!settings.topOnEmptyHash) return;
|
||||
anchor = document.documentElement;
|
||||
} else {
|
||||
anchor = document.querySelector(hash);
|
||||
}
|
||||
anchor = !anchor && hash === '#top' ? document.documentElement : anchor;
|
||||
|
||||
// If anchored element exists, scroll to it
|
||||
if (!anchor) return;
|
||||
event.preventDefault();
|
||||
setHistory(settings);
|
||||
smoothScroll.animateScroll(anchor, toggle);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Animate scroll on popstate events
|
||||
*/
|
||||
var popstateHandler = function (event) {
|
||||
|
||||
// Stop if history.state doesn't exist (ex. if clicking on a broken anchor link).
|
||||
// fixes `Cannot read property 'smoothScroll' of null` error getting thrown.
|
||||
if (history.state === null) return;
|
||||
|
||||
// Only run if state is a popstate record for this instantiation
|
||||
if (!history.state.smoothScroll || history.state.smoothScroll !== JSON.stringify(settings)) return;
|
||||
|
||||
// Only run if state includes an anchor
|
||||
|
||||
// if (!history.state.anchor && history.state.anchor !== 0) return;
|
||||
|
||||
// Get the anchor
|
||||
var anchor = history.state.anchor;
|
||||
if (typeof anchor === 'string' && anchor) {
|
||||
anchor = document.querySelector(escapeCharacters(history.state.anchor));
|
||||
if (!anchor) return;
|
||||
}
|
||||
|
||||
// Animate scroll to anchor link
|
||||
smoothScroll.animateScroll(anchor, null, {updateURL: false});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy the current initialization.
|
||||
*/
|
||||
smoothScroll.destroy = function () {
|
||||
|
||||
// If plugin isn't already initialized, stop
|
||||
if (!settings) return;
|
||||
|
||||
// Remove event listeners
|
||||
document.removeEventListener('click', clickHandler, false);
|
||||
window.removeEventListener('popstate', popstateHandler, false);
|
||||
|
||||
// Cancel any scrolls-in-progress
|
||||
smoothScroll.cancelScroll();
|
||||
|
||||
// Reset variables
|
||||
settings = null;
|
||||
anchor = null;
|
||||
toggle = null;
|
||||
fixedHeader = null;
|
||||
eventTimeout = null;
|
||||
animationInterval = null;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize Smooth Scroll
|
||||
* @param {Object} options User settings
|
||||
*/
|
||||
var init = function () {
|
||||
|
||||
// feature test
|
||||
if (!supports()) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.';
|
||||
|
||||
// Destroy any existing initializations
|
||||
smoothScroll.destroy();
|
||||
|
||||
// Selectors and variables
|
||||
settings = extend(defaults, options || {}); // Merge user options with defaults
|
||||
fixedHeader = settings.header ? document.querySelector(settings.header) : null; // Get the fixed header
|
||||
|
||||
// When a toggle is clicked, run the click handler
|
||||
document.addEventListener('click', clickHandler, false);
|
||||
|
||||
// If updateURL and popState are enabled, listen for pop events
|
||||
if (settings.updateURL && settings.popstate) {
|
||||
window.addEventListener('popstate', popstateHandler, false);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Initialize plugin
|
||||
//
|
||||
|
||||
init();
|
||||
|
||||
|
||||
//
|
||||
// Public APIs
|
||||
//
|
||||
|
||||
return smoothScroll;
|
||||
|
||||
};
|
||||
|
||||
return SmoothScroll;
|
||||
|
||||
}));
|
||||
34
fet2020/static/js/toolkit-screen@1.0.0.js
Normal file
34
fet2020/static/js/toolkit-screen@1.0.0.js
Normal file
@@ -0,0 +1,34 @@
|
||||
(() => {
|
||||
// packages/$screen/src/index.js
|
||||
function src_default(Alpine) {
|
||||
let data = Alpine.reactive({screensize: window.innerWidth});
|
||||
const defaultBreakpoints = {
|
||||
xs: 0,
|
||||
sm: 640,
|
||||
md: 768,
|
||||
lg: 1024,
|
||||
xl: 1280,
|
||||
"2xl": 1536
|
||||
};
|
||||
const breakpoints = window.AlpineMagicHelpersConfig && window.AlpineMagicHelpersConfig.breakpoints ? window.AlpineMagicHelpersConfig.breakpoints : defaultBreakpoints;
|
||||
let update;
|
||||
window.addEventListener("resize", () => {
|
||||
clearTimeout(update);
|
||||
update = setTimeout(() => data.screensize = window.innerWidth, 150);
|
||||
});
|
||||
Alpine.magic("screen", (el) => (breakpoint) => {
|
||||
let width = data.screensize;
|
||||
if (Number.isInteger(breakpoint))
|
||||
return breakpoint <= width;
|
||||
if (breakpoints[breakpoint] === void 0) {
|
||||
throw Error("Undefined $screen property: " + breakpoint + ". Supported properties: " + Object.keys(breakpoints).join(", "));
|
||||
}
|
||||
return breakpoints[breakpoint] <= width;
|
||||
});
|
||||
}
|
||||
|
||||
// packages/$screen/builds/cdn.js
|
||||
document.addEventListener("alpine:init", () => {
|
||||
window.Alpine.plugin(src_default);
|
||||
});
|
||||
})();
|
||||
200639
fet2020/static/styles.css
Normal file
200639
fet2020/static/styles.css
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,23 +1,31 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="grid-container padding-top-1">
|
||||
<div class="grid-x">
|
||||
|
||||
<form action="" method="post">
|
||||
<h3>Anmeldung für FET-Mitarbeiter</h3>
|
||||
<!-- Main Content -->
|
||||
<main class="container mx-auto w-full px-4 my-8 flex-grow flex flex-col">
|
||||
<h1 class="page-title">Login für FET-Mitarbeiter</h1>
|
||||
<div class="w-full h-full flex-1 flex justify-center items-center">
|
||||
<form action="" method="POST" class="sm:p-4 sm:w-3/5 md:w-1/2 lg:w-2/5 xl:w-1/3 2xl:w-1/4 grid grid-cols-1 gap-3 sm:gap-6">
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
<input type="submit" class="button" name="btn_input" value="Anmelden">
|
||||
|
||||
{% for message in messages %}
|
||||
<p id="messages">{{message}}</p>
|
||||
<div class="alert alert-danger">
|
||||
<i class="alert-icon fas fa-check-circle"></i>
|
||||
<h2 class="alert-title">Fehler:</h2>
|
||||
<div class="alert-body">{{ message }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Username</span>
|
||||
<input type="text" name="username" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50 placeholder-gray-400" required="required">
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Passwort</span>
|
||||
<input type="password" name="password" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50 placeholder-gray-400" required="required">
|
||||
</label>
|
||||
<input type="submit" class="block btn btn-primary" value="Anmelden">
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
{% endblock %}
|
||||
|
||||
152
fet2020/templates/base.html
Normal file
152
fet2020/templates/base.html
Normal file
@@ -0,0 +1,152 @@
|
||||
{% load static %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>FET: Startseite</title>
|
||||
|
||||
<meta name="author" content="Fachschaft Elektrotechnik (FET)">
|
||||
<meta name="description" content="Die Fachschaft Elektrotechnik besteht aus ET Studierenden, die sich um die Anliegen der Studenten und Studentinnen kümmern.">
|
||||
<meta property="og:image" content="#"> <!--og:... = Facebook metadata-->
|
||||
<meta property="og:description" content="Die Fachschaft Elektrotechnik besteht aus ET Studierenden, die sich um die Anliegen der Studenten und Studentinnen kümmern.">
|
||||
<meta property="og:title" content="Fachschaft Elektrotechnik (FET)">
|
||||
<meta name="twitter:title" content="Fachschaft Elektrotechnik (FET)">
|
||||
<meta name="theme-color" content="#006599">
|
||||
<!-- third-generation iPad with high-resolution Retina display: -->
|
||||
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="#">
|
||||
<!-- iPhone with high-resolution Retina display: -->
|
||||
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="#">
|
||||
<!-- first- and second-generation iPad: -->
|
||||
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="#">
|
||||
<!-- non-Retina iPhone, iPod Touch, and Android 2.1+ devices: -->
|
||||
<link rel="apple-touch-icon-precomposed" href="#">
|
||||
<!-- basic favicon -->
|
||||
<link rel="icon" href="#">
|
||||
<link rel="shortcut icon" type="image/png" href="{% static 'img/fet_logo_white.png' %}">
|
||||
|
||||
<link rel="stylesheet" href="{% static 'styles.css' %}">
|
||||
<!--<link rel="stylesheet" href="../css/tailwind.css">-->
|
||||
<!--<script src="https://kit.fontawesome.com/fb26f70535.js" crossorigin="anonymous"></script>-->
|
||||
<link rel="stylesheet" href="{% static 'fontawesomefree/css/all.min.css' %}" type="text/css">
|
||||
|
||||
<!--Google Fonts-->
|
||||
<!--
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&display=swap">
|
||||
|
||||
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
|
||||
-->
|
||||
{% block extraheader %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- NAVBAR -->
|
||||
<nav class="navbar" x-data="{ showNavBar: false }">
|
||||
<div>
|
||||
<a href="{% url 'home' %}">
|
||||
<img src="{% static 'img/logo2014_64.png' %}" alt="FET-Logo" class="navbar-logo">
|
||||
</a>
|
||||
<button class="navbar-toggle"
|
||||
@click="showNavBar = ! showNavBar"
|
||||
>
|
||||
<i class="fas fa-bars"></i>
|
||||
</button>
|
||||
<ul id="navBarContent" class="navbar-content sm:block"
|
||||
x-show="showNavBar || $screen('sm')"
|
||||
x-transition:enter="transition ease-out duration-300"
|
||||
x-transition:enter-start="transform opacity-0"
|
||||
x-transition:enter-end="transform opacity-100"
|
||||
x-transition:leave="transition ease-in duration-150"
|
||||
x-transition:leave-start="transform opacity-100"
|
||||
x-transition:leave-end="transform opacity-0"
|
||||
>
|
||||
<li><a href="{% url 'posts:posts.index' %}">News</a></li>
|
||||
<li><a href="{% url 'members_view' 'A' %}">Fachschaft</a></li>
|
||||
<li><a href="/fotos/">Fotos</a></li>
|
||||
<li><a href="{% url 'blackboard' %}">Blackboard</a></li>
|
||||
<li><a href="{% url 'contact' %}">Kontakt</a></li>
|
||||
|
||||
{% if not request.user.is_authenticated %}
|
||||
<li><a href="{% url 'login' %}?next={{ request.path }}">Login</a></li>
|
||||
{% else %}
|
||||
<hr class="border-proprietary">
|
||||
<div href="#" class="inline-block w-full sm:w-auto rounded relative"
|
||||
x-data="{ showPopupNav: false }"
|
||||
@click.outside="showPopupNav = false"
|
||||
>
|
||||
<div class="sm:inline-flex items-center divide-x divide-blue-200 bg-proprietary text-blue-50 rounded">
|
||||
<a class="hidden sm:block flex-1 px-2 py-1 hover:bg-proprietary-dark active:bg-proprietary-darker rounded-l" href="#"
|
||||
@click="showPopupNav = !showPopupNav"
|
||||
>
|
||||
{% if request.user.first_name %}
|
||||
Hallo {{ request.user.first_name }}
|
||||
{% else %}
|
||||
Hallo {{ request.user.username }}
|
||||
{% endif %}
|
||||
</a>
|
||||
<a class="hidden sm:block flex-0 px-2 py-1 hover:bg-proprietary-dark focus:bg-proprietary-darker rounded-r" href="{% url 'logout' %}?next={{ request.path }}"><i class="fa-solid fa-power-off"></i></a>
|
||||
</div>
|
||||
<div class="sm:block sm:absolute z-20 top-9 right-0 bg-white sm:shadow-md sm:rounded w-full"
|
||||
x-show="showPopupNav || !$screen('sm')"
|
||||
x-transition:enter="transition ease-out duration-300"
|
||||
x-transition:enter-start="transform origin-top opacity-0 scale-95"
|
||||
x-transition:enter-end="transform origin-top opacity-100 scale-100"
|
||||
x-transition:leave="transition ease-in duration-150"
|
||||
x-transition:leave-start="transform origin-top opacity-100 scale-100"
|
||||
x-transition:leave-end="transform origin-top opacity-0 scale-95"
|
||||
>
|
||||
<li class="navInternal"><a href="{% url 'admin:index' %}"><i class="fa-fw fa-solid fa-user-secret mr-2"></i>Admin</a></li>
|
||||
<li class="navInternal"><a href="{% url 'tasks' %}"><i class="fa-fw fa-solid fa-list-check mr-2"></i>Tasks</a></li>
|
||||
<li class="navInternal"><a href="https://legacy.fet.at/home/intern"><i class="fa-fw fa-solid fa-database mr-2"></i>Intern</a></li>
|
||||
<li class="navInternal"
|
||||
x-show="!$screen('sm')"
|
||||
><a href="{% url 'logout' %}?next={{ request.path }}"><i class="fa-fw fa-solid fa-power-off mr-2"></i>Logout</a></li>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
<footer class="bg-proprietary p-4 text-blue-100 flex-none">
|
||||
<ul class="flex justify-center mb-4 text-2xl">
|
||||
<li class="mx-4">
|
||||
<a href="https://facebook.fet.at/"><i class="fab fa-facebook"></i></a>
|
||||
</li>
|
||||
<li class="mx-4">
|
||||
<a href="https://instagram.fet.at/"><i class="fab fa-instagram"></i></a>
|
||||
</li>
|
||||
<li class="mx-4">
|
||||
<a href="https://discord.fet.at/"><i class="fab fa-discord"></i></a>
|
||||
</li>
|
||||
<li class="mx-4">
|
||||
<a href="https://telegram.fet.at/"><i class="fab fa-telegram"></i></a>
|
||||
</li>
|
||||
<li class="mx-4">
|
||||
<a href="mailto:service@fet.at"><i class="fas fa-envelope"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="flex justify-center my-4">
|
||||
<a href="{% url 'impressum' %}" class="text-center text-sm sm:text-base">Impressum</a>
|
||||
</div>
|
||||
<hr class="border-blue-300 -mx-4">
|
||||
<p class="mt-4 uppercase text-center text-sm sm:text-base">© {% now 'Y' %} FET - Alle Rechte vorbehalten.</p>
|
||||
</footer>
|
||||
<div class="text-center p-2 bg-gray-800 text-gray-400 font-light" x-data="{ counter: 0 }">
|
||||
<span :class="counter>=4 && 'text-purple-300'">Handcrafted </span><span :class="counter>=5 && 'text-green-400'">with </span><i class="fa-solid fa-heart" aria-label="love" @click="counter++" :class="counter>=2 ? 'text-proprietary hover:text-proprietary-dark' : 'text-red-600 hover:text-red-700'"></i><span :class="counter>=6 && 'text-pink-400'"> by</span><span class="font-normal" :class="counter>=3 && 'text-yellow-500'"> Matteo Duchscher</span>
|
||||
</div>
|
||||
|
||||
<script async src="{% static 'js/alpinejs@3.2.2.js' %}" defer></script>
|
||||
<script src="{% static 'js/toolkit-screen@1.0.0.js' %}" defer></script>
|
||||
|
||||
<script async="async" src="{% static 'js/scripts.js' %}"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,46 +1,70 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Main Content -->
|
||||
<main class="container mx-auto w-full px-4 mt-8 flex-1">
|
||||
<h1 class="page-title">Blackboard</h1>
|
||||
|
||||
<div class="grid-container padding-top-1">
|
||||
{% if request.user.is_authenticated %}
|
||||
<div class="grid-x">
|
||||
<div class="cell large-3 medium-4 small-12">
|
||||
<a class="button" href="{% url 'admin:blackboard_jobposting_add' %}">neue Stellenausschreibung hinzufügen</a>
|
||||
</div>
|
||||
|
||||
{% if bb_info %}
|
||||
<div class="cell large-3 medium-4 small-12">
|
||||
<a class="button" href="{% url 'admin:core_customflatpage_change' bb_info.id %}">Info-Text bearbeiten</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if bb_empty %}
|
||||
<div class="cell large-3 medium-4 small-12">
|
||||
<a class="button" href="{% url 'admin:core_customflatpage_change' bb_empty.id %}">"leeres Blackboard"-Text bearbeiten</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<hr>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h1>Blackboard</h1>
|
||||
|
||||
<div class="lg:w-2/3 xl:w-7/12 mx-auto">
|
||||
<section class="my-8 flex flex-col gap-2">
|
||||
<div class="db-page-content">
|
||||
<!-- Content from DB here: -->
|
||||
{% if bb_info %}
|
||||
{{ bb_info.content|safe }}
|
||||
<hr>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if request.user.is_authenticated and bb_info %}
|
||||
<a href="{% url 'admin:core_customflatpage_change' bb_info.id %}" class="self-center sm:self-end btn-small btn-primary w-full sm:w-auto max-w-sm">
|
||||
<i class="fa-regular fa-pen-to-square mr-1"></i>Info-Text bearbeiten
|
||||
</a>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
{% if job_postings %}
|
||||
<section class="my-8 flex flex-col gap-2">
|
||||
<div class="jobsList">
|
||||
{% for job in job_postings %}
|
||||
{% if not forloop.first %}
|
||||
<hr class="border-gray-300">
|
||||
{% endif %}
|
||||
|
||||
<div class="grid-x grid-margin-x">
|
||||
{% for job in job_postings %}
|
||||
{% include 'blackboard/partials/_show_job_posting.html' %}
|
||||
{% empty %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
<div class="inline-flex flex-col sm:flex-row sm:justify-end gap-2 w-full sm:w-auto">
|
||||
<a href="{% url 'admin:blackboard_jobposting_add' %}" class="self-center block btn-small btn-primary w-full sm:w-auto max-w-sm">
|
||||
<i class="fa-regular fa-square-plus mr-1"></i>Neuer Eintrag
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
{% else %}
|
||||
<section class="my-8 p-8 flex flex-col gap-2 items-center border-2 border-dashed rounded border-gray-300">
|
||||
{% if bb_empty %}
|
||||
<div class="cell large-3 medium-4 small-12">
|
||||
<div class="text-center text-gray-600">
|
||||
<i class="fa-solid fa-sparkles text-gray-400 text-2xl mb-4"></i>
|
||||
{{ bb_empty.content|safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
<div class="inline-flex flex-col sm:flex-row gap-2 w-full sm:w-auto">
|
||||
<a href="{% url 'admin:blackboard_jobposting_add' %}" class="self-center block btn-small btn-primary w-full sm:w-auto max-w-sm">
|
||||
<i class="fa-regular fa-square-plus mr-1"></i>Neuer Eintrag
|
||||
</a>
|
||||
{% if bb_empty %}
|
||||
<a href="{% url 'admin:core_customflatpage_change' bb_empty.id %}" class="self-center block btn-small btn-primary w-full sm:w-auto max-w-sm">
|
||||
<i class="fa-solid fa-asterisk mr-1"></i>Fülltext bearbeiten
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endif %}
|
||||
</div>
|
||||
</main>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
<div class="cell large-3 medium-4 small-12">
|
||||
<a href="{{ job.pdf_location.url }}" class="jobsList-item">
|
||||
<div class="jobsList-desc">
|
||||
<h2>{{ job.company_name }}</h2>
|
||||
<p>{{job.job_name}}<br>
|
||||
|
||||
{% if job.number_of_hours == 1 %}
|
||||
Mindestgehalt: {{job.salary}}€ Stundenlohn<br></p>
|
||||
{% else %}
|
||||
monatliches Mindestgehalt:<br>
|
||||
{{job.salary}}€ für {{job.number_of_hours}}h</p>
|
||||
{% endif %}
|
||||
|
||||
{# only thumb and name of member #}
|
||||
<a class="thumbnail member-thumb" href="{{job.pdf_location.url}}" style="width:200px;height:280px" target="_blank">
|
||||
<img style="width:200px;height:280px" src="{{job.pdf_thumb_location}}" alt="" />
|
||||
<div class="thumb-layer">
|
||||
<div>
|
||||
<h1>{{job.company_name}}</h1>
|
||||
<p>{{job.job_name}}</p>
|
||||
<h3>{{ job.job_name }}</h3>
|
||||
</div>
|
||||
<div class="jobsList-price">
|
||||
<p class="jobsList-value">{{ job.salary }}€</p>
|
||||
<p class="jobsList-amount ">/ {{ job.number_of_hours }} <span class="sm:hidden">h</span><span class="hidden sm:inline">Stunden</span></p>
|
||||
</div>
|
||||
<div class="jobsList-expand">
|
||||
<i class="fas fa-angle-right"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,103 +1,93 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% load post_helpers %}
|
||||
{% load static %}
|
||||
|
||||
{% block content %}
|
||||
<!--Hero section-->
|
||||
<section class="hero-image relative z-0 w-full h-56 sm:h-80 lg:h-96 bg-cover-image bg-cover bg-center bg-no-repeat flex-none">
|
||||
<div class="absolute z-10 w-full h-full bg-blue-50 opacity-60"></div>
|
||||
<div class="relative container px-4 mx-auto z-20 w-full h-full flex flex-wrap items-center gap-x-2">
|
||||
<h1 class="w-3/5 flex-1 uppercase font-semibold text-xl sm:text-2xl lg:text-3xl text-center text-gray-900">
|
||||
<span class="hidden">Willkommen bei der </span><span>Fachschaft</span><br>
|
||||
<span class="text-proprietary-darker">Elektrotechnik</span>
|
||||
</h1>
|
||||
<div class="hidden sm:block flex-none w-2/5 lg:w-1/3 bg-white p-2 lg:p-4 rounded shadow-xl">
|
||||
<h2 class="section-title sm:text-left"><i class="fas fa-comments text-gray-300 mr-2"></i>Events</h2>
|
||||
<div class="-mb-2 text-gray-700 text-sm md:text-base">
|
||||
|
||||
|
||||
<div class="grid-x small-padding-left-1">
|
||||
<div class="medium-8 small cell" style="background: grey">
|
||||
{% with post=featured_post %}
|
||||
<a href="{{ post.url }}">
|
||||
<div class="news-hero-large"style="background-image: url('{{ post.imageurl }}');)">
|
||||
<div class="news-hero-text">
|
||||
<hr>
|
||||
<div class="article-date">
|
||||
<p>{{ post.date|date:"d. F Y" }}</p>
|
||||
</div>
|
||||
<div class="article-title">
|
||||
<h1>{{ post.title|safe }}</h1>
|
||||
<p>{{ post.subtitle|default_if_none:" "|safe }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
<div class="cell medium-4 responsive-side-box">
|
||||
|
||||
<div class="article-row-section">
|
||||
<div class="article-row-section-inner">
|
||||
|
||||
<h1 class="article-row-section-header">Events</h1>
|
||||
|
||||
{% if featured_event %}
|
||||
{% with post=featured_event %}
|
||||
{% include 'posts/partials/_article_row.html' %}
|
||||
{% include 'posts/partials/_meeting_row.html' %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% for post in featured_meeting %}
|
||||
{% include 'posts/partials/_meeting_row.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-container">
|
||||
<div class="grid-x grid-padding-x padding-top-1 padding-left-1 padding-right-1">
|
||||
{{ tags_list|tags_to_url }}
|
||||
</div>
|
||||
</div>
|
||||
<!--<div class="w-full self-end flex justify-center mb-4">
|
||||
<i class="fas fa-chevron-down animate-bounce text-proprietary text-2xl"></i>
|
||||
</div>-->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="grid-x grid-x-padding">
|
||||
<div class="large-8 medium-7 small-12 small-order-2 medium-order-1">
|
||||
{% for post in posts %}
|
||||
{% include 'posts/partials/_posts_hero.html' %}
|
||||
<!-- Main Content -->
|
||||
<main class="container mx-auto w-full px-4 my-8 flex-1">
|
||||
<section class="sm:hidden my-8">
|
||||
<h2 class="section-title section-title-margins">Events</h2>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
{% if featured_event %}
|
||||
{% with post=featured_event %}
|
||||
{% include 'posts/partials/_article_row.html' %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% for post in featured_meeting %}
|
||||
{% include 'posts/partials/_article_row.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="large-4 medium-5 small-12 small-order-1 medium-order-1 padding-top-1 large-padding-left-1 medium-padding-left-1">
|
||||
|
||||
<a href="mailto:service@fet.at">
|
||||
<div class="social-media-box">
|
||||
<span class="social-media-badge badge">
|
||||
<span class="social-media-badge-symbol">
|
||||
<i class="fa-solid fa-envelope"></i>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span class="social-media-text">Schreib uns ein Mail :)</span>
|
||||
</div>
|
||||
</a>
|
||||
<a href="{% url 'discord' %}">
|
||||
<div class="social-media-box">
|
||||
<span class="social-media-badge badge">
|
||||
<span class="social-media-badge-symbol">
|
||||
<i class="fa-brands fa-discord"></i>
|
||||
</span>
|
||||
</span>
|
||||
<span class="social-media-text">Komm auf unseren Discord-Server!</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="sm:flex sm:flex-row-reverse justify-center my-8">
|
||||
<aside class="calendar-preview sm:w-2/5 xl:w-1/4 sm:pl-4 my-8 sm:my-0">
|
||||
<div>
|
||||
<h2 class="section-title section-title-margins">Kalender</h2>
|
||||
<div class="calendar-entries">
|
||||
{% for post in events %}
|
||||
{% include 'posts/partials/_date_box.html' %}
|
||||
{% endfor %}
|
||||
|
||||
<a href="{% url 'posts:posts.calendar' %}">
|
||||
<div class="social-media-box">
|
||||
<span class="social-media-badge badge">
|
||||
<span class="social-media-badge-symbol">
|
||||
<i class="fa-regular fa-calendar"></i>
|
||||
</span>
|
||||
</span>
|
||||
<span class="social-media-text">FET-Kalender abonnieren</span>
|
||||
<a href="https://fet.at/posts/fet_calendar.ics" class="btn btn-secondary block w-full"><i class="fas fa-calendar-alt mr-2"></i>Kalender abonnieren</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<section class="my-8 sm:my-0 sm:w-3/5 xl:w-2/5 flex flex-col gap-4">
|
||||
<h2 class="section-title section-title-margins">Zuletzt veröffentlicht</h2>
|
||||
|
||||
{% for post in posts %}
|
||||
{% include 'posts/partials/_posts_hero.html' %}
|
||||
{% endfor %}
|
||||
|
||||
<a href="{% url 'posts:posts.index' %}" class="btn btn-primary block w-full"><i class="fas fa-plus-square mr-2"></i>Mehr anzeigen</a>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div id="infoBox" class="sticky bottom-4 p-4 rounded-lg shadow-lg bg-gray-600 text-gray-200 flex gap-x-4 items-center leading-none">
|
||||
<div class="flex-none relative">
|
||||
<span class="absolute flex h-3 w-3 right-0 top-0">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-500 opacity-80"></span>
|
||||
<span class="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
|
||||
</span>
|
||||
<i class="fab fa-discord text-4xl"></i>
|
||||
</div>
|
||||
<a href="https://discord.fet.at/" class="flex-1">
|
||||
FET Discord-Server<br>
|
||||
<span class="hidden lg:inline text-sm text-gray-300">Du hast Fragen zum Studium oder möchtest dich einfach mich anderen Studierenden austauschen? </span><span class="text-sm text-gray-300">Klicke hier zum Beitreten <span class="hidden sm:inline"><i class="fa-solid fa-angle-right"></i></span></span>
|
||||
</a>
|
||||
<button id="infoBox-closeButton" class="flex-none self-stretch px-2 -mr-2" onclick="hideInfoBox()"><i class="fas fa-times text-gray-400"></i></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<a class="button" href="{% url 'posts:posts.index' %}" style="background: gray">Mehr anzeigen</a>
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
{% endblock %}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<link rel="shortcut icon" type="image/png" href="{% static 'img/fet_logo_white.png' %}"/>
|
||||
<link rel="stylesheet" href="{% static 'app.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'fet.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'intern.css' %}">
|
||||
<link href="{% static 'fontawesomefree/css/all.min.css' %}" rel="stylesheet" type="text/css">
|
||||
{% block galleryheader %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,61 +1,111 @@
|
||||
{% extends "layout.html" %}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% load softhyphen_tags %}
|
||||
{% load static %}
|
||||
|
||||
{% block content %}
|
||||
<div class="grid-container">
|
||||
|
||||
<div class="grid-x grid-padding-x padding-top-1">
|
||||
|
||||
{% for job in pinned_job_groups %}
|
||||
<div class="cell large-2 medium-4 small-6">
|
||||
<a class="button job-btn {% if job.slug in request.path %} active {% endif %}" href="{% url 'jobs' job.slug %}">
|
||||
{{ job.name|softhyphen|safe }}
|
||||
</a>
|
||||
<!-- Main Content -->
|
||||
<main class="container mx-auto w-full px-4 mt-8 flex-1">
|
||||
<h1 class="page-title">Über uns</h1>
|
||||
<div class="sm:flex sm:flex-row justify-center my-8">
|
||||
<aside class="flex-none max-w-min sm:mr-8">
|
||||
<div class="fixed sm:sticky top-0 sm:top-4 left-0 w-full h-full sm:h-auto bg-black sm:bg-transparent bg-opacity-70 flex sm:block items-center justify-center"
|
||||
x-show="showModal || $screen('sm')"
|
||||
x-transition:enter="transition duration-300 ease-out"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition duration-150 ease-in"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
>
|
||||
<div class="max-w-sm sm:w-full mx-4 sm:mx-0 p-4 sm:p-0 bg-white sm:bg-transparent rounded sm:rounded-none"
|
||||
@click.outside="showModal = false"
|
||||
x-show="showModal || $screen('sm')"
|
||||
x-transition:enter="transition transform ease-out duration-300"
|
||||
x-transition:enter-start="scale-110 opacity-0"
|
||||
x-transition:enter-end="scale-100 opacity-100"
|
||||
x-transition:leave="transition transform ease-in duration-150"
|
||||
x-transition:leave-start="scale-100 opacity-100"
|
||||
x-transition:leave-end="scale-110 opacity-0"
|
||||
>
|
||||
<div class="flex justify-between items-center mb-2 sm:hidden">
|
||||
<h2 class="text-gray-800 sm:section-title sm_section-title-margins sm:w-full">
|
||||
<span class="mr-1 text-gray-400 sm:hidden">
|
||||
<i class="fa-solid fa-bars"></i>
|
||||
</span>
|
||||
Kategorien
|
||||
</h2>
|
||||
<div class="ml-4 -mr-2 px-2 rounded text-xl text-gray-600 sm:hidden cursor-pointer" @click="showModal = false">
|
||||
<i class="far fa-times"></i>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="sideBarNav">
|
||||
{% for job in pinned_job_groups %}
|
||||
<li class="{% if job.slug in request.path %} active {% endif %}">
|
||||
<a href="{% url 'jobs' job.slug %}">{{ job.name|softhyphen|safe }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
{% for job in unpinned_job_groups %}
|
||||
<div class="cell large-2 medium-4 small-6">
|
||||
<a class="button job-btn {% if job.slug in request.path %} active {% endif %} job-btn" href="{% url 'jobs' job.slug %}">
|
||||
{{ job.name|softhyphen|safe }}
|
||||
</a>
|
||||
</div>
|
||||
<li class="{% if job.slug in request.path %} active {% endif %}">
|
||||
<a href="{% url 'jobs' job.slug %}">{{ job.name|softhyphen|safe }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
<div class="cell large-2 medium-4 small-6">
|
||||
<a class="button memb-btn {% if 'pension' in request.path %} active {% endif %}" href="{% url 'members_view' 'pension' %}">
|
||||
Pension
|
||||
</a>
|
||||
</div>
|
||||
<hr class="">
|
||||
|
||||
<div class="cell large-2 medium-4 small-6">
|
||||
<a class="button memb-btn {% if '/members/' == request.path %} active {% endif %}" href="{% url 'members' %}">
|
||||
Alle Mitglieder
|
||||
</a>
|
||||
</div>
|
||||
<li class="{% if '/members/P' == request.path %} active {% endif %}">
|
||||
<a href="{% url 'members_view' 'P' %}">Pension</a>
|
||||
</li>
|
||||
|
||||
</div>
|
||||
<li class="{% if '/members/' == request.path %} active {% endif %}">
|
||||
<a href="{% url 'members' %}">Alle Mitglieder</a>
|
||||
</li>
|
||||
|
||||
<li class="active"><a href="#">Studienkommission</a></li>
|
||||
<ul id="scrollspy-subNav">
|
||||
<li class="active"><a href="#stuko-computational-science">Studienkommission Computational Science</a></li>
|
||||
<li><a href="#stuko-et">Studienkommission ET</a></li>
|
||||
<li><a href="#stuko-ulg">Studienkommission Universitätslehrgänge</a></li>
|
||||
</ul>
|
||||
|
||||
<li class="internalLI"><a href="#"><i class="fa-regular fa-pen-to-square mr-1"></i>Bearbeiten</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button id="modal-trigger-1" class="trigger fixed bottom-4 right-4 bg-proprietary-darker text-blue-50 shadow-lg text-2xl rounded sm:hidden"
|
||||
@click="showModal = true"
|
||||
x-show="!showModal && !$screen('sm')"
|
||||
x-transition:enter="transition duration-100 ease-in"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition duration-100 ease-out"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
>
|
||||
<i class="fa-solid fa-bars px-2 py-1"></i>
|
||||
</button>
|
||||
</aside>
|
||||
|
||||
<section class="flex-grow max-w-prose my-8 sm:my-0">
|
||||
{% if description %}
|
||||
<div class="grid-x">
|
||||
<div class="cell padding-top-1 padding-left-1 padding-right-1" style="background-color: white; text-align: justify;">
|
||||
<div class="db-page-content text-gray-800">
|
||||
{{ description|safe }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- show details of a member -->
|
||||
{% if member %}
|
||||
<!-- show details of a member -->
|
||||
{% block members_content %}
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
<!-- show all, active or pension members -->
|
||||
{% if members %}
|
||||
<div class="grid-x">
|
||||
<div class="cell padding-top-1 padding-left-1 padding-right-1" style="background-color: white; text-align: justify;">
|
||||
<!-- show all, active or pension members -->
|
||||
{% if fs_info %}
|
||||
<div class="db-page-content text-gray-800">
|
||||
{{ fs_info.content|safe }}
|
||||
</div>
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
<hr>
|
||||
@@ -63,42 +113,42 @@
|
||||
<hr>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="padding-top-1 padding-left-1 padding-right-1" style="background-color: white;">
|
||||
{% include 'members/members_list.html' %}
|
||||
<article class="members-article">
|
||||
<div class="members-listing">
|
||||
{% for member in members %}
|
||||
{% include 'members/partials/_member.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</article>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<!-- show job lists in a job group -->
|
||||
{% include 'members/jobs_list.html' %}
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{% endblock %}
|
||||
<script src="{% static 'js/gumshoe@5.1.1.js' %}"></script>
|
||||
<script src="{% static 'js/smooth-scroll@16.1.2.js' %}"></script>
|
||||
<script src="{% static 'js/toolkit-screen@1.0.0.js' %}" defer></script>
|
||||
<script defer src="{% static 'js/alpinejs@3.2.2.js' %}"></script>
|
||||
<script defer src="{% static 'js/scripts.js' %}"></script>
|
||||
|
||||
<script>
|
||||
// Get the container element
|
||||
var btnContainer = document.getElementById("grid-container");
|
||||
|
||||
// Get all buttons with class="btn" inside the container
|
||||
var grid = btnContainer.getElementsByClassName("grid-x");
|
||||
var cell = grid.getElementsByClassName("cell");
|
||||
var btns = cell.getElementsByClassName("button");
|
||||
|
||||
// Loop through the buttons and add the active class to the current/clicked button
|
||||
for (var i = 0; i < btns.length; i++) {
|
||||
btns[i].addEventListener("click", function() {
|
||||
var current = document.getElementsByClassName("active");
|
||||
|
||||
// If there's no active class
|
||||
if (current.length > 0) {
|
||||
current[0].className = current[0].className.replace(" active", "");
|
||||
}
|
||||
|
||||
// Add the active class to the current/clicked button
|
||||
this.className += " active";
|
||||
var spy = new Gumshoe('#scrollspy-subNav a', {
|
||||
/***** Scrollspy *****/ // Active classes
|
||||
navClass: 'font-semibold', // applied to the nav list item
|
||||
});
|
||||
|
||||
/***** SmoothScroll *****/ // All animations will take exactly 500ms
|
||||
var scroll = new SmoothScroll('a[href*="#"]', {
|
||||
speed: 750,
|
||||
speedAsDuration: true,
|
||||
easing: 'easeInOutQuad'
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
{% regroup job_members by job.name as all_jobmem_list %}
|
||||
|
||||
{% for jobmem in all_jobmem_list %}
|
||||
|
||||
<div class="padding-top-1 padding-left-1 padding-right-1" style="background-color: white;">
|
||||
|
||||
<h2>{{jobmem.grouper}}<a class="headerlink" id="{{jobmem.list.0.job.slug}}" href="#{{jobmem.list.0.job.slug}}" title="Permalink to {{jobmem.grouper}}"> #</a></h2>
|
||||
|
||||
<div class="grid-x align-bottom">
|
||||
|
||||
<article id="{{jobmem.list.0.job.slug}}" class="members-article">
|
||||
<a href="#{{jobmem.list.0.job.slug}}" class="title">
|
||||
<i class="far fa-link"></i>
|
||||
<h2>{{jobmem.grouper}}</h2>
|
||||
</a>
|
||||
<div class="members-listing">
|
||||
{% for jm in jobmem.list %}
|
||||
{% with member=jm.member %}
|
||||
{% include 'members/partials/_job_membership_grid.html' %}
|
||||
{% include 'members/partials/_member.html' %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
{% endfor %}
|
||||
@@ -8,7 +8,5 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block members_content %}
|
||||
<div class="padding-top-1 padding-left-1 padding-bottom-1 padding-right-1" style="background-color: white;">
|
||||
{% include 'members/partials/_member_details.html' %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
<div class="grid-x align-bottom">
|
||||
{% for member in members %}
|
||||
<div class="cell large-2 medium-3 small-6 padding-right-1" style="text-align: center">
|
||||
@@ -7,4 +6,3 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
{# only thumb and name of member #}
|
||||
<a class="thumbnail member-thumb" href="{{ member.get_absolute_url }}" style="width:150px; height:150px">
|
||||
<img src="{{ member.image.thumb.url }}" alt="" />
|
||||
<div class="thumb-layer">
|
||||
<div>
|
||||
<h1>{{member.nickname}}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<figure>
|
||||
<a href="{{ member.get_absolute_url }}">
|
||||
<img loading="lazy" src="{{ member.image.thumb.url }}" alt="Portraitfoto von {{ member.firstname }}" class="w-36 h-36 bg-white">
|
||||
<figcaption>
|
||||
<h3>{{ member.firstname }} {{ member.surname }}</h3>
|
||||
</figcaption>
|
||||
</a>
|
||||
</figure>
|
||||
|
||||
@@ -1,26 +1,71 @@
|
||||
{# This template shows one member and all the details (that are ment for public) including a list of current jobs #}
|
||||
{% load softhyphen_tags %}
|
||||
{% load static %}
|
||||
|
||||
<div class="media-object stack-for-small">
|
||||
<div class="media-object-section padding-bottom-2">
|
||||
<img src= "{{member.image.portrait.url}}" style="width:150px;">
|
||||
<section class="flex-grow max-w-prose my-8 sm:my-0 text-justify text-gray-800">
|
||||
<!-- Alternativtext auf jede Person anpassen: Name im alt="" dynamisch erzeugen -->
|
||||
<img loading="lazy" src="{{ member.image.portrait.url }}" alt="Portraitfoto von {{ member.firstname }} {{ member.surname }}" class="md:float-left w-36 mr-2 mb-2">
|
||||
<div x-data="{ expandList: false }">
|
||||
<h2 class="mb-2 text-lg text-gray-900 text-left">{{ member.firstname }} {{ member.surname }}</h2>
|
||||
<div class="mb-2">
|
||||
Spitzname: {{ member.nickname }} <br>
|
||||
Mailaccount: {{ member.mailaccount }} <br>
|
||||
</div>
|
||||
<div class="media-object-section main-section padding-bottom-1"">
|
||||
{% if request.user.is_authenticated %}
|
||||
<a href="{% url 'admin:members_member_change' member.id %}">Profil bearbeiten</a>
|
||||
<hr>
|
||||
{% endif %}
|
||||
<h1>{{ member.firstname }} {{ member.surname }}</h1>
|
||||
<p>Spitzname: {{ member.nickname }} </br>
|
||||
Mailaccount: {{ member.mailaccount }} </br>
|
||||
</p>
|
||||
<div class="mb-2">
|
||||
{{ member.description|softhyphen|safe }}
|
||||
</p>
|
||||
</div>
|
||||
{% if jobs %}
|
||||
Ehrenamtliche Tätigkeiten: </br>
|
||||
<h3 class="group mt-4 mb-2 text-lg text-gray-900">Ehrenamtliche Tätigkeiten:
|
||||
<button class="inline float-right text-sm px-2 py-1 text-gray-600 md:text-gray-500 group-hover:text-gray-600 border rounded border-gray-500 md:border-gray-400 group-hover:border-gray-500"
|
||||
@click="expandList = ! expandList"
|
||||
>
|
||||
<span x-show="!expandList">Mehr</span><span x-show="expandList">Weniger</span><span class="hidden md:inline"> anzeigen</span>
|
||||
<i class="fa-fw fa-solid fa-angle-left transition transform -ml-1"
|
||||
:class="expandList ? '-rotate-90' : ''"
|
||||
></i>
|
||||
</button>
|
||||
</h3>
|
||||
|
||||
<ul class="flex flex-col gap-1">
|
||||
{% for jobm in jobs %}
|
||||
{{ jobm.job.name }}: {{ jobm.job_start|date }} - {{ jobm.job_end|date }} </br>
|
||||
<li class="flex flex-row flex-wrap">
|
||||
<span>{{ jobm.job.name }}:</span>
|
||||
<span class="ml-2 text-gray-600">{{ jobm.job_start|date }} -</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<ul class="flex flex-col gap-1 mt-1"
|
||||
x-show="expandList"
|
||||
x-transition:enter="transition duration-100 ease-in"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition duration-100 ease-out"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
>
|
||||
{% for jobm in jobs %}
|
||||
<li class="flex flex-row flex-wrap">
|
||||
<span>{{ jobm.job.name }}:</span>
|
||||
<span class="ml-2 text-gray-600">{{ jobm.job_start|date }} -</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script src="{% static 'gumshoe.js' %}"></script>
|
||||
<script src="{% static 'smooth-scroll.js' %}"></script>
|
||||
<script>
|
||||
var spy = new Gumshoe('#scrollspy-subNav a', {
|
||||
/***** Scrollspy *****/ // Active classes
|
||||
navClass: 'font-semibold', // applied to the nav list item
|
||||
});
|
||||
|
||||
/***** SmoothScroll *****/ // All animations will take exactly 500ms
|
||||
var scroll = new SmoothScroll('a[href*="#"]', {
|
||||
speed: 750,
|
||||
speedAsDuration: true,
|
||||
easing: 'easeInOutQuad'
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,132 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% load post_helpers %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Main Content -->
|
||||
<main class="container mx-auto w-full px-4 my-8 flex-1">
|
||||
<h1 class="page-title">News</h1>
|
||||
<div class="sm:flex sm:flex-row-reverse justify-center">
|
||||
<aside class="sm:w-2/5 sm:max-w-xs sm:pl-4 lg:pl-8 my-8 sm:my-0">
|
||||
<div class="z-10 fixed sm:sticky top-0 sm:top-4 lg:top-8 left-0 w-full h-full sm:h-auto bg-black sm:bg-transparent bg-opacity-70 flex sm:block items-center justify-center"
|
||||
x-show="showModal || $screen('sm')"
|
||||
x-transition:enter="transition duration-300 ease-out"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition duration-150 ease-in"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
>
|
||||
<div class="max-w-sm sm:w-full mx-4 sm:mx-0 p-4 rounded bg-white sm:shadow-lg"
|
||||
@click.outside="showModal = ! showModal"
|
||||
x-show="showModal || $screen('sm')"
|
||||
x-transition:enter="transition transform ease-out duration-300"
|
||||
x-transition:enter-start="scale-110 opacity-0"
|
||||
x-transition:enter-end="scale-100 opacity-100"
|
||||
x-transition:leave="transition transform ease-in duration-150"
|
||||
x-transition:leave-start="scale-100 opacity-100"
|
||||
x-transition:leave-end="scale-110 opacity-0"
|
||||
>
|
||||
<div class="flex justify-between items-center mb-2">
|
||||
<h2 class="text-gray-800 sm:section-title sm_section-title-margins sm:w-full">
|
||||
<span class="mr-1 text-gray-400 sm:hidden">
|
||||
<i class="fas fa-filter"></i>
|
||||
</span>
|
||||
Auswahl einschränken
|
||||
</h2>
|
||||
<div class="ml-4 -mr-2 px-2 rounded text-xl text-gray-600 sm:hidden cursor-pointer" @click="showModal = false">
|
||||
<i class="far fa-times"></i>
|
||||
</div>
|
||||
</div>
|
||||
<form action="" method="POST" class="grid grid-cols-1 gap-2 sm:gap-4" x-data="{ selectedYear: '' }">
|
||||
{% csrf_token %}
|
||||
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-danger">
|
||||
<i class="alert-icon fas fa-exclamation-circle"></i>
|
||||
<h2 class="alert-title">Fehler:</h2>
|
||||
<div class="alert-body">{{message}}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
|
||||
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Jahr</span>
|
||||
<select class="block w-full mt-1 rounded-md border-gray-300 shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50"
|
||||
x-model="selectedYear"
|
||||
id="id_year"
|
||||
name="year"
|
||||
>
|
||||
|
||||
</select>
|
||||
</label>
|
||||
<label
|
||||
x-show="selectedYear != ''"
|
||||
x-transition:enter="transition ease-out duration-300"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition ease-in duration-150"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
>
|
||||
<span class="text-gray-700">Monat</span>
|
||||
<select class="block w-full mt-1 rounded-md border-gray-300 shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50">
|
||||
<option value="" selected></option>
|
||||
<option value="1">Jänner</option>
|
||||
<option value="2">Februar</option>
|
||||
<option value="3">März</option>
|
||||
<option value="4">April</option>
|
||||
<option value="5">Mai</option>
|
||||
<option value="6">Juni</option>
|
||||
<option value="7">Juli</option>
|
||||
<option value="8">August</option>
|
||||
<option value="9">September</option>
|
||||
<option value="10">Oktober</option>
|
||||
<option value="11">November</option>
|
||||
<option value="12">Dezember</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="inline-flex items-center">
|
||||
<input type="checkbox" class="rounded border-gray-300 text-proprietary shadow-sm focus:border-blue-300 focus:ring focus:ring-offset-0 focus:ring-blue-200 focus:ring-opacity-50">
|
||||
<span class="ml-2 text-gray-700">Kompakte Ansicht</span>
|
||||
</label>
|
||||
<label class="inline-flex items-center">
|
||||
<input type="checkbox" class="rounded border-gray-300 text-proprietary shadow-sm focus:border-blue-300 focus:ring focus:ring-offset-0 focus:ring-blue-200 focus:ring-opacity-50">
|
||||
<span class="ml-2 text-gray-700">nur FET-Sitzungen</span>
|
||||
</label>
|
||||
<input type="submit" class="block btn btn-primary" value="Anzeigen">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<button id="modal-trigger-1" class="z-10 trigger fixed bottom-4 right-4 bg-proprietary-darker text-blue-50 shadow-lg text-2xl rounded sm:hidden"
|
||||
@click="showModal = true"
|
||||
x-show="! showModal"
|
||||
x-transition:enter="transition duration-100 ease-in"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition duration-100 ease-out"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
>
|
||||
<i class="fas fa-filter p-2"></i>
|
||||
</button>
|
||||
</aside>
|
||||
|
||||
<section class="my-8 sm:my-0 sm:w-3/5 xl:w-2/5 flex flex-col gap-4">
|
||||
{% if compact_view %}
|
||||
{% for post in posts %}
|
||||
{% include 'posts/partials/_posts_hero_compact.html' %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for post in posts %}
|
||||
{% include 'posts/partials/_posts_hero.html' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="grid-container">
|
||||
<div class="grid-x grid-margin-x">
|
||||
<div class="cell medium-8">
|
||||
@@ -37,21 +162,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="grid-x">
|
||||
<div class="cell medium-8">
|
||||
|
||||
{% if compact_view %}
|
||||
{% for post in posts %}
|
||||
{% include 'posts/partials/_posts_hero_compact.html' %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for post in posts %}
|
||||
{% include 'posts/partials/_posts_hero.html' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
<a href="{{ post.url }}">
|
||||
<article class="article-row">
|
||||
<div class="article-row-content">
|
||||
<h1 class="article-row-content-header">{{post.title}}</h1>
|
||||
{% if post.subtitle is not None %}
|
||||
<p class="article-row-content-description">{{post.subtitle}}</p>
|
||||
{% endif %}
|
||||
<!--<p class="article-row-content-author">{{post.author}}</p>-->
|
||||
<time class="article-row-content-time">{{post.event_start|date}}</time>
|
||||
</div>
|
||||
</article>
|
||||
<a href="{{ post.url }}" class="block">
|
||||
<h3 class="text-gray-700">{{ post.title }}</h3>
|
||||
<p class="my-1 text-sm text-gray-600">
|
||||
<i class="fas fa-calendar-alt text-gray-500"></i>
|
||||
<span>{{ post.event_start|date }} · {{ post.event_start|time }} Uhr</span>
|
||||
</p>
|
||||
</a>
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
<a href="{{ post.url }}">
|
||||
<div class="date-box">
|
||||
<span>
|
||||
<span class="date-badge badge primary" style="">
|
||||
<span class="date-badge-day">{{post.event_start|date:"d"}}</span>
|
||||
<span class="date-badge-month">{{post.event_start|date:"M"}}</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="date-text"><strong>{{post.title}}</strong></span>
|
||||
<a href="{{ post.url }}" class="calendar-entry">
|
||||
<div class="calendar-dateBubble">
|
||||
<span class="dateBubble-day">{{ post.event_start|date:"d" }}</span>
|
||||
<span class="dateBubble-month">{{ post.event_start|date:"M" }}</span>
|
||||
</div>
|
||||
<h3>{{ post.title }}</h3>
|
||||
</a>
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
<div class="my-2">
|
||||
<a href="{{ post.url }}">
|
||||
<article class="article-row">
|
||||
<div class="article-row-content">
|
||||
<h1 class="article-row-content-header">{{post.title}}</h1>
|
||||
{% if post.subtitle is not None %}
|
||||
<p class="article-row-content-description">{{post.subtitle}}</p>
|
||||
{% endif %}
|
||||
<time class="article-row-content-time" datetime="2008-02-14 20:00">{{post.event_start}}</time>
|
||||
</div>
|
||||
</article>
|
||||
<h3 class="">{{ post.title }}</h3>
|
||||
<p class="py-1 text-sm lg:text-base text-gray-600">
|
||||
<i class="fas fa-calendar-alt text-gray-500"></i>
|
||||
<span>{{ post.event_start|date }} · {{ post.event_start|time }} Uhr</span>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
<a href="{{ post.url }}">
|
||||
<div class="news-hero padding-bottom-1" style="background-image:url('{{ post.imageurl }}')">
|
||||
<div class="news-hero-text">
|
||||
<h1>{{ post.title | safe }}</h1>
|
||||
<h2>{{ post.subtitle|default_if_none:" " }}</h2>
|
||||
<p>{{ post.date|date:"d. F Y" }}</p>
|
||||
<article class="article-cover-image" style="background-image: url('{{ post.imageurl }}');" onclick="openArticle('{{ post.url }}')">
|
||||
<div class="article-cover-desc">
|
||||
<div class="article-cover-desc-items">
|
||||
<ul class="article-cover-tags">
|
||||
<li><a href="#">#fet</a></li>
|
||||
<li><a href="#">#ug</a></li>
|
||||
<li><a href="#">#öh</a></li>
|
||||
</ul>
|
||||
<div>
|
||||
<a href="{{ post.url }}"><h3 class="text-gray-50">{{ post.title | safe }}</h3></a>
|
||||
<div class="text-gray-200">
|
||||
<i class="fas fa-clock"></i>
|
||||
{% if post.post_type != 'N' %}
|
||||
{{ post.event_start|date:"d. F Y" }}
|
||||
{% else %}
|
||||
{{ post.public_date|date:"d. F Y" }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<a href="{{ post.url }}">
|
||||
<div class="news-hero-compact">
|
||||
<div class="news-hero-compact-text">
|
||||
<p style="margin-bottom: 0rem;">{{ post.title | safe | truncatechars:60 }}</p>
|
||||
</div>
|
||||
|
||||
<div class="news-hero-compact-right">
|
||||
<p style="margin-bottom: 0rem;">{{ post.date|date:"d. F Y" }}</p>
|
||||
</div>
|
||||
<article class="bg-white rounded shadow transition-all duration-300 hover:shadow-md transform hover:scale-105">
|
||||
<a href="{{ post.url }}" class="block p-4">
|
||||
<div class="float-right px-2 py-0.5 rounded-full text-sm font-medium text-proprietary bg-blue-100">
|
||||
<i class="fa-solid fa-calendar-days mr-1"></i>
|
||||
{% if post.post_type != 'N' %}
|
||||
<p style="margin-bottom: 0rem;">{{ post.event_start|date:"d. F Y" }}</p>
|
||||
{% else %}
|
||||
<p style="margin-bottom: 0rem;">{{ post.public_date|date:"d. F Y" }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<h3 class="text-gray-800 leading-relaxed">{{ post.title | safe | truncatechars:60 }}</h3>
|
||||
</a>
|
||||
</article>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "layout.html" %}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% load post_helpers %}
|
||||
{% load admin_urls %}
|
||||
|
||||
@@ -10,71 +11,123 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="large-article-header" style="background-image:url('{{ post.imageurl }}')">
|
||||
<div class="large-article-header-content">
|
||||
<div class="center-container">
|
||||
<div class="article-date">
|
||||
<p>{{ post.date|date:"d. F Y" }}</p>
|
||||
</div>
|
||||
|
||||
<div class="article-title">
|
||||
<h1>{{ post.title|tags_to_url }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="article-details">
|
||||
<a>
|
||||
{{ post.subtitle|default_if_none:" "|tags_to_url }}
|
||||
<!-- Main Content -->
|
||||
<main class="container mx-auto w-full flex-1 my-8 sm:flex flex-col sm:px-4">
|
||||
<a href="#" class="hidden z-20 fixed left-0 top-1/2 -mt-8 p-2 xl:flex items-center text-gray-400 rounded-md"
|
||||
x-data="{ showPrevArticleButton : false }"
|
||||
@mouseleave="showPrevArticleButton = false"
|
||||
@mouseover="showPrevArticleButton = true"
|
||||
>
|
||||
<i class="fa-light fa-chevron-left text-5xl -m-2 p-2 bg-gray-100 rounded-md"></i>
|
||||
<span class="text-gray-600 font-medium bg-gray-100 -m-2 p-2 rounded-r-md"
|
||||
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"
|
||||
>Vorheriger<br>Artikel</span>
|
||||
</a>
|
||||
<a href="{% url 'posts:posts.show' next %}" class="hidden z-20 fixed right-0 top-1/2 -mt-8 p-2 xl:flex items-center text-gray-400 rounded-md"
|
||||
x-data="{ showNextArticleButton : false }"
|
||||
@mouseleave="showNextArticleButton = false"
|
||||
@mouseover="showNextArticleButton = true"
|
||||
>
|
||||
<span class="z-30 text-gray-600 font-medium bg-gray-100 -m-2 p-2 rounded-l-md text-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ächster<br>Artikel</span>
|
||||
<i class="fa-light fa-chevron-right text-5xl -m-2 p-2 bg-gray-100 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-blue-700 text-sm uppercase tracking-wide sm:font-medium">
|
||||
<li class="inline-block py-1 px-2 bg-blue-100 rounded-full"><a href="#">#fachschaft</a></li>
|
||||
<li class="inline-block py-1 px-2 bg-blue-100 rounded-full"><a href="#">#WelcomeDay</a></li>
|
||||
<li class="inline-block py-1 px-2 bg-blue-100 rounded-full"><a href="#">#Inskriptionsberatung</a></li>
|
||||
</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 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 %}
|
||||
<div class="article-author">
|
||||
<a href="{% url 'member' author.id %}">
|
||||
<img src="{{ author_image }}" alt="" /> {{ author.firstname }}
|
||||
</a>
|
||||
|
||||
<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 text-sm sm:text-base">
|
||||
<a href="{% url 'member' author.id %}" class="underline">{{ author.firstname }}</a>
|
||||
<span class="sm:hidden"> am </span>
|
||||
<span>{{ post.public_date|date:"d. F Y" }}</span>
|
||||
</div>
|
||||
|
||||
{% elif post.author %}
|
||||
<div class="article-author">
|
||||
<a href="">
|
||||
<img src="" alt="" />{{ post.author }}
|
||||
</a>
|
||||
|
||||
<div class="sm:flex flex-col justify-evenly text-gray-600 text-sm sm:text-base">
|
||||
<a class="underline">{{ post.author }}</a>
|
||||
<span class="sm:hidden"> am </span>
|
||||
<span>{{ post.public_date|date:"d. F Y" }}</span>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
<div class="article-author">
|
||||
<a href="">
|
||||
<img src="" alt="" />fet.at Redaktion
|
||||
|
||||
<div class="sm:flex flex-col justify-evenly text-gray-600 text-sm sm:text-base">
|
||||
<a class="underline">fet.at Redaktion</a>
|
||||
<span class="sm:hidden"> am </span>
|
||||
<span>{{ post.public_date|date:"d. F Y" }}</span>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
{% if post.post_type == 'N' %}
|
||||
<a href="{% url 'admin:posts_news_change' post.id %}" class="hidden sm:block btn-small btn-primary">
|
||||
<i class="fa-regular fa-pen-to-square mr-1"></i>Artikel bearbeiten
|
||||
</a>
|
||||
</div>
|
||||
{% elif post.post_type == 'E' %}
|
||||
<a href="{% url 'admin:posts_event_change' post.id %}" class="hidden sm:block btn-small btn-primary">
|
||||
<i class="fa-regular fa-pen-to-square mr-1"></i>Event bearbeiten
|
||||
</a>
|
||||
{% elif post.post_type == 'F' %}
|
||||
<a href="{% url 'admin:posts_fetmeeting_change' post.id %}" class="hidden sm:block btn-small btn-primary">
|
||||
<i class="fa-regular fa-pen-to-square mr-1"></i>FET Sitzung bearbeiten
|
||||
</a>
|
||||
{% endif %}
|
||||
{% 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 lg:h-64 xl:h-80 bg-center bg-no-repeat bg-cover sm:rounded-md mx-auto" style="background-image: url('{{ post.imageurl }}');">
|
||||
|
||||
{% if post.post_type != 'N' %}
|
||||
<div class="hidden absolute top-0 right-0 bg-white rounded-bl p-2 bg-opacity-80 lg:flex items-center gap-2">
|
||||
<i class="flex-0 fa-solid fa-calendar-clock text-gray-800"></i>
|
||||
<span class="flex-1 text-sm text-gray-800">
|
||||
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>
|
||||
</div>
|
||||
|
||||
<div class="grid-container">
|
||||
<div class="grid-x grid-padding-x padding-top-1">
|
||||
<div class="cell medium-8">
|
||||
{% for tag in post.get_tagnames %}
|
||||
{{ tag|tags_to_url }}
|
||||
{% endfor %}
|
||||
<hr>
|
||||
|
||||
{% if post.has_agenda %}
|
||||
<h2>Agenda<a class="headerlink" id="agenda" href="#agenda" title="Permalink to Agenda"> #</a></h2>
|
||||
{{ post.agenda_html|safe }}
|
||||
<hr>
|
||||
{% elif post.body %}
|
||||
{{ post.body|safe|add_internal_links|tags_to_url }}
|
||||
<hr>
|
||||
{% endif %}
|
||||
|
||||
{% if request.user.is_authenticated and post.has_protocol %}
|
||||
<h2>Protokoll<a class="headerlink" id="protocol" href="#protocol" title="Permalink to Protokoll"> #</a></h2>
|
||||
{{ post.protocol_html|safe }}
|
||||
<hr>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<div class="cell medium-4">
|
||||
<a href="{% url 'posts:posts.show' next %}">Nächster Artikel <span class="nav fa fa-chevron-right fa-1x"></span></a><br>
|
||||
</section>
|
||||
<section class="mx-4 z-10">
|
||||
<article class="p-4 mt-4 sm:-mt-16 w-full max-w-prose mx-auto bg-white rounded">
|
||||
<!-- <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">
|
||||
<!-- Content from DB here: -->
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
<hr>
|
||||
@@ -100,31 +153,21 @@
|
||||
<hr>
|
||||
{% endif %}
|
||||
|
||||
{% if post.post_type == 'N' %}
|
||||
<a href="{% url 'admin:posts_news_change' post.id %}">News bearbeiten</a>
|
||||
{% elif post.post_type == 'E' %}
|
||||
<a href="{% url 'admin:posts_event_change' post.id %}">Event bearbeiten</a>
|
||||
{% elif post.post_type == 'F' %}
|
||||
<a href="{% url 'admin:posts_fetmeeting_change' post.id %}">FET Sitzung bearbeiten</a>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if post.event_start %}
|
||||
{% if post.has_agenda %}
|
||||
<h2>Agenda</h2>
|
||||
{{ post.agenda_html|safe }}
|
||||
<hr>
|
||||
Start: {{ post.event_start|date:"d. F Y" }} {{ post.event_start|time:"H:i" }}<br>
|
||||
{% endif %}
|
||||
{% if post.event_end %}
|
||||
Ende: {{ post.event_end|date:"d. F Y" }} {{ post.event_end|time:"H:i" }}<br>
|
||||
{% elif post.body %}
|
||||
{{ post.body|safe|add_internal_links|tags_to_url }}
|
||||
{% endif %}
|
||||
|
||||
{% if post.event_place %}
|
||||
Ort: {{ post.event_place }}
|
||||
{% endif %}
|
||||
|
||||
{% if post.event_start %}
|
||||
{% include 'posts/partials/_date_box.html' %}
|
||||
{% if request.user.is_authenticated and post.has_protocol %}
|
||||
<h2>Protokoll</h2>
|
||||
{{ post.protocol_html|safe }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if files %}
|
||||
<hr>
|
||||
@@ -138,18 +181,65 @@
|
||||
|
||||
{% endif %}
|
||||
|
||||
<hr>
|
||||
|
||||
<hr class="lg:hidden -mx-4 border-gray-200 border-1 my-4">
|
||||
<div class="lg:hidden">
|
||||
<h2 class="text-gray-800 font-medium"><i class="fa-solid fa-calendar-days mr-2 text-gray-400"></i>Termindetails:</h2>
|
||||
<ul class="text-base text-gray-700 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>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<hr class="-mx-4 border-gray-200 border-1 my-4">
|
||||
<div class="-m-4 flex divide-x divide-gray-200 text-sm sm:text-base">
|
||||
<a href="#" class="w-1/2 p-4 flex items-center gap-2">
|
||||
<i class="fa-solid fa-chevron-left text-gray-600"></i>
|
||||
<span class="text-gray-700 font-medium">Vorheriger Artikel</span>
|
||||
</a>
|
||||
<a href="{% url 'posts: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"></i>
|
||||
<span class="text-gray-700 font-medium">Nächster Artikel</span>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
{% if post.post_type == 'N' %}
|
||||
<a href="{% url 'admin:posts_news_change' post.id %}" class="sm:hidden block w-full btn btn-primary mt-4">
|
||||
<i class="fa-regular fa-pen-to-square mr-1"></i>Artikel bearbeiten
|
||||
</a>
|
||||
{% elif post.post_type == 'E' %}
|
||||
<a href="{% url 'admin:posts_event_change' post.id %}" class="sm:hidden block w-full btn btn-primary mt-4">
|
||||
<i class="fa-regular fa-pen-to-square mr-1"></i>Event bearbeiten
|
||||
</a>
|
||||
{% elif post.post_type == 'F' %}
|
||||
<a href="{% url 'admin:posts_fetmeeting_change' post.id %}" class="sm:hidden block w-full btn btn-primary mt-4">
|
||||
<i class="fa-regular fa-pen-to-square mr-1"></i>FET Sitzung bearbeiten
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
{% if related_posts %}
|
||||
<section class="mx-auto w-full px-4">
|
||||
<h2 class="my-4 sm:my-8 text-proprietary text-xl text-center uppercase tracking-wider">Weiterlesen</h2>
|
||||
|
||||
<div class="grid-x grid-margin-x">
|
||||
{% for post in related_posts %}
|
||||
<div class="medium-6 large-4 small-12 cell">
|
||||
{% include 'posts/partials/_posts_hero.html' %}
|
||||
<a href="{{ post.url }}" class="sm:flex-1 block rounded bg-white shadow-md bg-no-repeat bg-center h-56 transition-all ease-in-out duration-500 bg-scale-100 hover:bg-scale-120" style="background-image: url('{{ post.imageurl }}');">
|
||||
<div class="w-full h-full bg-gradient-to-t from-black rounded-md flex flex-col justify-end p-2">
|
||||
<h2 class="text-gray-50 line-clamp-2"><span aria-label="Link zum Artikel: "></span>{{ post.title | safe }}</h2>
|
||||
<span class="text-gray-300 text-sm">
|
||||
<i class="fas fa-clock mr-1"></i>
|
||||
<span aria-label=" vom "></span>
|
||||
{% if post.post_type != 'N' %}
|
||||
{{ post.event_start|date:"d. F Y" }}
|
||||
{% else %}
|
||||
{{ post.public_date|date:"d. F Y" }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
</main>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user