first implementation of new layout

This commit is contained in:
2021-11-18 13:11:39 +00:00
committed by Patrick Mayr
parent 206a71fb6f
commit 98f5ff1f4a
26 changed files with 205328 additions and 514 deletions

View File

@@ -107,7 +107,7 @@ def profile_view(request, member_id=None):
logger.info("Wrong member id '{}'".format(member_id)) logger.info("Wrong member id '{}'".format(member_id))
raise Http404("no member") 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 = { context = {
"pinned_job_groups": pinned_job_groups, "pinned_job_groups": pinned_job_groups,

File diff suppressed because it is too large Load Diff

View 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;
}));

View 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;
}

View 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: theres 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;
}));

View 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

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,31 @@
{% extends 'layout.html' %} {% extends 'base.html' %}
{% block content %} {% block content %}
<!-- Main Content -->
<div class="grid-container padding-top-1"> <main class="container mx-auto w-full px-4 my-8 flex-grow flex flex-col">
<div class="grid-x"> <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"> <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">
<h3>Anmeldung für FET-Mitarbeiter</h3>
{% csrf_token %} {% csrf_token %}
{{ form }}
<input type="submit" class="button" name="btn_input" value="Anmelden">
{% for message in messages %} {% 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 %} {% 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> </form>
</div> </div>
</main>
</div>
{% endblock %} {% endblock %}

152
fet2020/templates/base.html Normal file
View 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>

View File

@@ -1,46 +1,70 @@
{% extends 'layout.html' %} {% extends 'base.html' %}
{% block content %} {% 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"> <div class="lg:w-2/3 xl:w-7/12 mx-auto">
{% if request.user.is_authenticated %} <section class="my-8 flex flex-col gap-2">
<div class="grid-x"> <div class="db-page-content">
<div class="cell large-3 medium-4 small-12"> <!-- Content from DB here: -->
<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>
{% if bb_info %} {% if bb_info %}
{{ bb_info.content|safe }} {{ 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 %} {% endif %}
<div class="grid-x grid-margin-x">
{% for job in job_postings %}
{% include 'blackboard/partials/_show_job_posting.html' %} {% 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 %} {% 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 }} {{ bb_empty.content|safe }}
</div> </div>
{% endif %} {% 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 %} {% endblock %}

View File

@@ -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> <h2>{{ job.company_name }}</h2>
<p>{{job.job_name}}<br> <h3>{{ job.job_name }}</h3>
{% 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>
</div> </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> </div>
</a> </a>
</div>

View File

@@ -1,103 +1,93 @@
{% extends 'layout.html' %} {% extends 'base.html' %}
{% load post_helpers %} {% load post_helpers %}
{% load static %} {% load static %}
{% block content %} {% 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">
{% if featured_event %}
<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:"&nbsp;"|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>
{% with post=featured_event %} {% with post=featured_event %}
{% include 'posts/partials/_article_row.html' %} {% include 'posts/partials/_meeting_row.html' %}
{% endwith %} {% endwith %}
{% endif %}
{% for post in featured_meeting %} {% for post in featured_meeting %}
{% include 'posts/partials/_meeting_row.html' %} {% include 'posts/partials/_meeting_row.html' %}
{% endfor %} {% 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>
<!--<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"> <!-- Main Content -->
<div class="large-8 medium-7 small-12 small-order-2 medium-order-1"> <main class="container mx-auto w-full px-4 my-8 flex-1">
{% for post in posts %} <section class="sm:hidden my-8">
{% include 'posts/partials/_posts_hero.html' %} <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 %} {% endfor %}
</div> </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"> <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">
<a href="mailto:service@fet.at"> <div>
<div class="social-media-box"> <h2 class="section-title section-title-margins">Kalender</h2>
<span class="social-media-badge badge"> <div class="calendar-entries">
<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>
{% for post in events %} {% for post in events %}
{% include 'posts/partials/_date_box.html' %} {% include 'posts/partials/_date_box.html' %}
{% endfor %} {% endfor %}
<a href="{% url 'posts:posts.calendar' %}"> <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 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-Ka­len­der abonnieren</span>
</div> </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> </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>
</main>
</div>
<a class="button" href="{% url 'posts:posts.index' %}" style="background: gray">Mehr anzeigen</a>
</div>
{% endblock %} {% endblock %}

View File

@@ -11,7 +11,6 @@
<link rel="shortcut icon" type="image/png" href="{% static 'img/fet_logo_white.png' %}"/> <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 'app.css' %}">
<link rel="stylesheet" href="{% static 'fet.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"> <link href="{% static 'fontawesomefree/css/all.min.css' %}" rel="stylesheet" type="text/css">
{% block galleryheader %} {% block galleryheader %}
{% endblock %} {% endblock %}

View File

@@ -1,61 +1,111 @@
{% extends "layout.html" %} {% extends 'base.html' %}
{% load softhyphen_tags %} {% load softhyphen_tags %}
{% load static %}
{% block content %} {% block content %}
<div class="grid-container"> <!-- Main Content -->
<main class="container mx-auto w-full px-4 mt-8 flex-1">
<div class="grid-x grid-padding-x padding-top-1"> <h1 class="page-title">Über uns</h1>
<div class="sm:flex sm:flex-row justify-center my-8">
{% for job in pinned_job_groups %} <aside class="flex-none max-w-min sm:mr-8">
<div class="cell large-2 medium-4 small-6"> <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"
<a class="button job-btn {% if job.slug in request.path %} active {% endif %}" href="{% url 'jobs' job.slug %}"> x-show="showModal || $screen('sm')"
{{ job.name|softhyphen|safe }} x-transition:enter="transition duration-300 ease-out"
</a> 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>
</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 %} {% endfor %}
{% for job in unpinned_job_groups %} {% for job in unpinned_job_groups %}
<div class="cell large-2 medium-4 small-6"> <li class="{% if job.slug in request.path %} active {% endif %}">
<a class="button job-btn {% if job.slug in request.path %} active {% endif %} job-btn" href="{% url 'jobs' job.slug %}"> <a href="{% url 'jobs' job.slug %}">{{ job.name|softhyphen|safe }}</a>
{{ job.name|softhyphen|safe }} </li>
</a>
</div>
{% endfor %} {% endfor %}
<div class="cell large-2 medium-4 small-6"> <hr class="">
<a class="button memb-btn {% if 'pension' in request.path %} active {% endif %}" href="{% url 'members_view' 'pension' %}">
Pension
</a>
</div>
<div class="cell large-2 medium-4 small-6"> <li class="{% if '/members/P' == request.path %} active {% endif %}">
<a class="button memb-btn {% if '/members/' == request.path %} active {% endif %}" href="{% url 'members' %}"> <a href="{% url 'members_view' 'P' %}">Pension</a>
Alle Mitglieder </li>
</a>
</div>
</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 %} {% if description %}
<div class="grid-x"> <div class="db-page-content text-gray-800">
<div class="cell padding-top-1 padding-left-1 padding-right-1" style="background-color: white; text-align: justify;">
{{ description|safe }} {{ description|safe }}
</div> </div>
</div>
{% endif %} {% endif %}
<!-- show details of a member -->
{% if member %} {% if member %}
<!-- show details of a member -->
{% block members_content %} {% block members_content %}
{% endblock %} {% endblock %}
{% endif %} {% endif %}
<!-- show all, active or pension members -->
{% if members %} {% if members %}
<div class="grid-x"> <!-- show all, active or pension members -->
<div class="cell padding-top-1 padding-left-1 padding-right-1" style="background-color: white; text-align: justify;">
{% if fs_info %} {% if fs_info %}
<div class="db-page-content text-gray-800">
{{ fs_info.content|safe }} {{ fs_info.content|safe }}
</div>
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<hr> <hr>
@@ -63,42 +113,42 @@
<hr> <hr>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div>
</div>
<div class="padding-top-1 padding-left-1 padding-right-1" style="background-color: white;"> <article class="members-article">
{% include 'members/members_list.html' %} <div class="members-listing">
{% for member in members %}
{% include 'members/partials/_member.html' %}
{% endfor %}
</div> </div>
</article>
{% endif %} {% endif %}
<div>
<!-- show job lists in a job group --> <!-- show job lists in a job group -->
{% include 'members/jobs_list.html' %} {% include 'members/jobs_list.html' %}
</div> </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> <script>
// Get the container element var spy = new Gumshoe('#scrollspy-subNav a', {
var btnContainer = document.getElementById("grid-container"); /***** Scrollspy *****/ // Active classes
navClass: 'font-semibold', // applied to the nav list item
// Get all buttons with class="btn" inside the container });
var grid = btnContainer.getElementsByClassName("grid-x");
var cell = grid.getElementsByClassName("cell"); /***** SmoothScroll *****/ // All animations will take exactly 500ms
var btns = cell.getElementsByClassName("button"); var scroll = new SmoothScroll('a[href*="#"]', {
speed: 750,
// Loop through the buttons and add the active class to the current/clicked button speedAsDuration: true,
for (var i = 0; i < btns.length; i++) { easing: 'easeInOutQuad'
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";
}); });
}
</script> </script>
{% endblock %}

View File

@@ -1,20 +1,17 @@
{% regroup job_members by job.name as all_jobmem_list %} {% regroup job_members by job.name as all_jobmem_list %}
{% for jobmem in all_jobmem_list %} {% for jobmem in all_jobmem_list %}
<article id="{{jobmem.list.0.job.slug}}" class="members-article">
<div class="padding-top-1 padding-left-1 padding-right-1" style="background-color: white;"> <a href="#{{jobmem.list.0.job.slug}}" class="title">
<i class="far fa-link"></i>
<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> <h2>{{jobmem.grouper}}</h2>
</a>
<div class="grid-x align-bottom"> <div class="members-listing">
{% for jm in jobmem.list %} {% for jm in jobmem.list %}
{% with member=jm.member %} {% with member=jm.member %}
{% include 'members/partials/_job_membership_grid.html' %} {% include 'members/partials/_member.html' %}
{% endwith %} {% endwith %}
{% endfor %} {% endfor %}
</div> </div>
</div> </article>
{% endfor %} {% endfor %}

View File

@@ -8,7 +8,5 @@
{% endblock %} {% endblock %}
{% block members_content %} {% 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' %} {% include 'members/partials/_member_details.html' %}
</div>
{% endblock %} {% endblock %}

View File

@@ -1,4 +1,3 @@
<div class="grid-x align-bottom"> <div class="grid-x align-bottom">
{% for member in members %} {% for member in members %}
<div class="cell large-2 medium-3 small-6 padding-right-1" style="text-align: center"> <div class="cell large-2 medium-3 small-6 padding-right-1" style="text-align: center">
@@ -7,4 +6,3 @@
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@@ -1,9 +1,8 @@
{# only thumb and name of member #} <figure>
<a class="thumbnail member-thumb" href="{{ member.get_absolute_url }}" style="width:150px; height:150px"> <a href="{{ member.get_absolute_url }}">
<img src="{{ member.image.thumb.url }}" alt="" /> <img loading="lazy" src="{{ member.image.thumb.url }}" alt="Portraitfoto von {{ member.firstname }}" class="w-36 h-36 bg-white">
<div class="thumb-layer"> <figcaption>
<div> <h3>{{ member.firstname }} {{ member.surname }}</h3>
<h1>{{member.nickname}}</h1> </figcaption>
</div>
</div>
</a> </a>
</figure>

View File

@@ -1,26 +1,71 @@
{# This template shows one member and all the details (that are ment for public) including a list of current jobs #} {# This template shows one member and all the details (that are ment for public) including a list of current jobs #}
{% load softhyphen_tags %} {% load softhyphen_tags %}
{% load static %}
<div class="media-object stack-for-small"> <section class="flex-grow max-w-prose my-8 sm:my-0 text-justify text-gray-800">
<div class="media-object-section padding-bottom-2"> <!-- Alternativtext auf jede Person anpassen: Name im alt="" dynamisch erzeugen -->
<img src= "{{member.image.portrait.url}}" style="width:150px;"> <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>
<div class="media-object-section main-section padding-bottom-1""> <div class="mb-2">
{% 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>
{{ member.description|softhyphen|safe }} {{ member.description|softhyphen|safe }}
</p> </div>
{% if jobs %} {% 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 %} {% 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 %} {% 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 %} {% endif %}
</div> </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>

View File

@@ -1,7 +1,132 @@
{% extends 'layout.html' %} {% extends 'base.html' %}
{% load post_helpers %} {% load post_helpers %}
{% block content %} {% 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-container">
<div class="grid-x grid-margin-x"> <div class="grid-x grid-margin-x">
<div class="cell medium-8"> <div class="cell medium-8">
@@ -37,21 +162,5 @@
</div> </div>
</div> </div>
</form> </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> </div>
{% endblock %} {% endblock %}

View File

@@ -1,12 +1,7 @@
<a href="{{ post.url }}"> <a href="{{ post.url }}" class="block">
<article class="article-row"> <h3 class="text-gray-700">{{ post.title }}</h3>
<div class="article-row-content"> <p class="my-1 text-sm text-gray-600">
<h1 class="article-row-content-header">{{post.title}}</h1> <i class="fas fa-calendar-alt text-gray-500"></i>
{% if post.subtitle is not None %} <span>{{ post.event_start|date }} · {{ post.event_start|time }} Uhr</span>
<p class="article-row-content-description">{{post.subtitle}}</p> </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> </a>

View File

@@ -1,11 +1,7 @@
<a href="{{ post.url }}"> <a href="{{ post.url }}" class="calendar-entry">
<div class="date-box"> <div class="calendar-dateBubble">
<span> <span class="dateBubble-day">{{ post.event_start|date:"d" }}</span>
<span class="date-badge badge primary" style=""> <span class="dateBubble-month">{{ post.event_start|date:"M" }}</span>
<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>
</div> </div>
<h3>{{ post.title }}</h3>
</a> </a>

View File

@@ -1,11 +1,9 @@
<div class="my-2">
<a href="{{ post.url }}"> <a href="{{ post.url }}">
<article class="article-row"> <h3 class="">{{ post.title }}</h3>
<div class="article-row-content"> <p class="py-1 text-sm lg:text-base text-gray-600">
<h1 class="article-row-content-header">{{post.title}}</h1> <i class="fas fa-calendar-alt text-gray-500"></i>
{% if post.subtitle is not None %} <span>{{ post.event_start|date }} · {{ post.event_start|time }} Uhr</span>
<p class="article-row-content-description">{{post.subtitle}}</p> </p>
{% endif %}
<time class="article-row-content-time" datetime="2008-02-14 20:00">{{post.event_start}}</time>
</div>
</article>
</a> </a>
</div>

View File

@@ -1,9 +1,22 @@
<a href="{{ post.url }}"> <article class="article-cover-image" style="background-image: url('{{ post.imageurl }}');" onclick="openArticle('{{ post.url }}')">
<div class="news-hero padding-bottom-1" style="background-image:url('{{ post.imageurl }}')"> <div class="article-cover-desc">
<div class="news-hero-text"> <div class="article-cover-desc-items">
<h1>{{ post.title | safe }}</h1> <ul class="article-cover-tags">
<h2>{{ post.subtitle|default_if_none:"&nbsp;" }}</h2> <li><a href="#">#fet</a></li>
<p>{{ post.date|date:"d. F Y" }}</p> <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>
</div> </div>
</a> </div>
</div>
</article>

View File

@@ -1,11 +1,13 @@
<a href="{{ post.url }}"> <article class="bg-white rounded shadow transition-all duration-300 hover:shadow-md transform hover:scale-105">
<div class="news-hero-compact"> <a href="{{ post.url }}" class="block p-4">
<div class="news-hero-compact-text"> <div class="float-right px-2 py-0.5 rounded-full text-sm font-medium text-proprietary bg-blue-100">
<p style="margin-bottom: 0rem;">{{ post.title | safe | truncatechars:60 }}</p> <i class="fa-solid fa-calendar-days mr-1"></i>
</div> {% if post.post_type != 'N' %}
<p style="margin-bottom: 0rem;">{{ post.event_start|date:"d. F Y" }}</p>
<div class="news-hero-compact-right"> {% else %}
<p style="margin-bottom: 0rem;">{{ post.date|date:"d. F Y" }}</p> <p style="margin-bottom: 0rem;">{{ post.public_date|date:"d. F Y" }}</p>
</div> {% endif %}
</div> </div>
<h3 class="text-gray-800 leading-relaxed">{{ post.title | safe | truncatechars:60 }}</h3>
</a> </a>
</article>

View File

@@ -1,4 +1,5 @@
{% extends "layout.html" %} {% extends 'base.html' %}
{% load post_helpers %} {% load post_helpers %}
{% load admin_urls %} {% load admin_urls %}
@@ -10,71 +11,123 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="large-article-header" style="background-image:url('{{ post.imageurl }}')"> <!-- Main Content -->
<div class="large-article-header-content"> <main class="container mx-auto w-full flex-1 my-8 sm:flex flex-col sm:px-4">
<div class="center-container"> <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"
<div class="article-date"> x-data="{ showPrevArticleButton : false }"
<p>{{ post.date|date:"d. F Y" }}</p> @mouseleave="showPrevArticleButton = false"
</div> @mouseover="showPrevArticleButton = true"
>
<div class="article-title"> <i class="fa-light fa-chevron-left text-5xl -m-2 p-2 bg-gray-100 rounded-md"></i>
<h1>{{ post.title|tags_to_url }}</h1> <span class="text-gray-600 font-medium bg-gray-100 -m-2 p-2 rounded-r-md"
</div> x-show="showPrevArticleButton"
x-transition:enter="transition ease-out duration-300"
<div class="article-details"> x-transition:enter-start="opacity-0 bg-opacity-0 transform scale-90"
<a> x-transition:enter-end="opacity-100 transform scale-100"
{{ post.subtitle|default_if_none:"&nbsp;"|tags_to_url }} 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>
<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 %} {% if author_image and author %}
<div class="article-author">
<a href="{% url 'member' author.id %}"> <img class="hidden sm:block w-12 rounded-full" src="{{ author_image }}" alt="Portraitfoto von {{ author.firstname }}">
<img src="{{ author_image }}" alt="" />&nbsp;{{ author.firstname }} <div class="sm:flex flex-col justify-evenly text-gray-600 text-sm sm:text-base">
</a> <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> </div>
{% elif post.author %} {% elif post.author %}
<div class="article-author">
<a href=""> <div class="sm:flex flex-col justify-evenly text-gray-600 text-sm sm:text-base">
<img src="" alt="" />{{ post.author }} <a class="underline">{{ post.author }}</a>
</a> <span class="sm:hidden"> am </span>
<span>{{ post.public_date|date:"d. F Y" }}</span>
</div> </div>
{% else %} {% else %}
<div class="article-author">
<a href=""> <div class="sm:flex flex-col justify-evenly text-gray-600 text-sm sm:text-base">
<img src="" alt="" />fet.at Redaktion <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> </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 %} {% endif %}
</div> </div>
</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>
<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 %} {% endif %}
</div> </div>
<div class="cell medium-4"> </section>
<a href="{% url 'posts:posts.show' next %}">Nächster Artikel <span class="nav fa fa-chevron-right fa-1x"></span></a><br> <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 %} {% if request.user.is_authenticated %}
<hr> <hr>
@@ -100,31 +153,21 @@
<hr> <hr>
{% endif %} {% 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 %}
{% endif %} {% if post.has_agenda %}
<h2>Agenda</h2>
{% if post.event_start %} {{ post.agenda_html|safe }}
<hr> <hr>
Start: {{ post.event_start|date:"d. F Y" }} {{ post.event_start|time:"H:i" }}<br> {% elif post.body %}
{% endif %} {{ post.body|safe|add_internal_links|tags_to_url }}
{% if post.event_end %}
Ende: {{ post.event_end|date:"d. F Y" }} {{ post.event_end|time:"H:i" }}<br>
{% endif %} {% endif %}
{% if post.event_place %} {% if request.user.is_authenticated and post.has_protocol %}
Ort: {{ post.event_place }} <h2>Protokoll</h2>
{% endif %} {{ post.protocol_html|safe }}
{% if post.event_start %}
{% include 'posts/partials/_date_box.html' %}
{% endif %} {% endif %}
</div>
{% if files %} {% if files %}
<hr> <hr>
@@ -138,18 +181,65 @@
{% endif %} {% 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:&Tab;{{ post.event_start|date }} um {{ post.event_start|time }} Uhr</li>
<li>Ende:&Tab;{{ post.event_end|date }} um {{ post.event_end|time }} Uhr</li>
</ul>
</div> </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> </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 %} {% for post in related_posts %}
<div class="medium-6 large-4 small-12 cell"> <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 }}');">
{% include 'posts/partials/_posts_hero.html' %} <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> </div>
</a>
{% endfor %} {% endfor %}
</div> </section>
</div> {% endif %}
</main>
{% endblock %} {% endblock %}