Merge branch 'feat/course_detail' into 'master'

Übersichtlichere Kurs-Seiten

See merge request !28
This commit is contained in:
Felix Hamann 2018-04-26 22:27:24 +02:00
commit e277fcf7df
10 changed files with 1909 additions and 65 deletions

View File

@ -456,9 +456,12 @@ defaultMenuLayout menu widget = do
pc <- widgetToPageContent $ do
addStylesheetRemote "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,800,900"
addScript $ StaticR js_featureChecker_js
addScript $ StaticR js_zepto_js
addScript $ StaticR js_fetchPolyfill_js
addScript $ StaticR js_urlPolyfill_js
addScript $ StaticR js_featureChecker_js
addScript $ StaticR js_tabber_js
addStylesheet $ StaticR css_tabber_css
addStylesheet $ StaticR css_fonts_css
addStylesheet $ StaticR css_icons_css
$(widgetFile "default-layout")

42
static/css/tabber.css Normal file
View File

@ -0,0 +1,42 @@
.tab-group {
box-shadow: 0 0 0 18px white, 0 0 0 20px #b3b7c1;
margin-top: 40px;
}
.tab-group-openers {
display: flex;
justify-content: stretch;
line-height: 40px;
font-size: 14px;
margin-bottom: 40px;
}
.tab-opener {
display: inline-block;
flex: 1;
text-align: center;
padding: 0 13px;
margin: 0 2px;
background-color: #b3b7c1;
color: white;
font-size: 16px;
text-transform: uppercase;
font-weight: 600;
transition: all .2s ease;
box-shadow: inset 0 -4px 4px rgba(0, 0, 0, 0.1);
border-top: 5px solid transparent;
}
.tab-opener:not(.tab-visible):hover {
cursor: pointer;
background-color: transparent;
color: rgb(52, 48, 58);
box-shadow: none;
border-top-color: grey;
}
.tab-opener.tab-visible {
background-color: transparent;
color: rgb(52, 48, 58);
border-top-color: #5F98C2;
box-shadow: none;
}

88
static/js/tabber.js Normal file
View File

@ -0,0 +1,88 @@
(function($) {
document.addEventListener('DOMContentLoaded', function() {
'use strict';
// define plugin
$.fn.tabgroup = function() {
var $this = $(this);
var $openers = $('<div class="tab-group-openers"></div>');
$this.prepend($openers);
var openedByDefault = $this.data('tab-open') || 0;
var tabs = [];
var currentTab = {};
$this.find('.tab').each(function(i, t) {
var tab = $(t);
tab.data('tab-index', i);
var tabName = tab.data('tab-name') || 'Tab '+i;
var tabFile = tab.data('tab-file') || false;
var $opener = makeOpener(tabName, i);
$openers.append($opener);
if (tab.find('.tab-title')) {
tab.find('.tab-title').remove();
}
tab.hide();
var loaded = false;
tabs.push({index: i, name: tabName, file: tabFile, dom: tab, opener: $opener, loaded: false});
});
$this.on('click', 'a[href^="#"]', function(event) {
var $target = $(event.currentTarget);
var tab = getTabByName($target.attr('href').replace('#', ''));
if ( tab ) {
showTab(tab.index);
}
event.preventDefault();
});
function getTabByName(name) {
var it = -1;
$.each(tabs, function(i, t) {
if ( t.name.toLowerCase() === name.toLowerCase() ) {
it = i;
}
});
if ( it >= 0 ) {
return tabs[it];
} else {
return false;
}
}
function makeOpener(tabName, i) {
return $('<span class="tab-opener">'+tabName+'</span>').
on('click', function() {
showTab(i);
});
}
function showTab(i) {
tabs.forEach(function(t) {
t.dom.hide();
t.opener.removeClass('tab-visible');
});
currentTab = tabs[i];
if ( !currentTab.loaded && currentTab.file ){
$.get(currentTab.file, function(res) {
currentTab.dom.html(res);
currentTab.loaded = true;
});
}
currentTab.opener.addClass('tab-visible');
currentTab.dom.show();
}
showTab(openedByDefault);
currentTab = tabs[openedByDefault];
};
// apply plugin to all available tab-groups
$('.tab-group').each(function(i, t) {
$(t).tabgroup();
})
});
})($);

1650
static/js/zepto.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +1,102 @@
<div .course-header>
<div .course-header__info>
<table>
<tr>
<th>Teilnehmer
<td>
#{participants}
$maybe capacity <- courseCapacity course
\ von #{capacity}
<tr>
<th>Anmeldezeitraum
<td>
$maybe regFrom <- courseRegisterFrom course
#{formatTimeGerWD regFrom}
$maybe regTo <- courseRegisterTo course
\ bis #{formatTimeGerWD regTo}
<div>
<form method=post action=@{CourseR tid csh CourseShowR} enctype=#{regEnctype}>
^{regWidget}
<div .course-header__title>
<h1>#{courseName course}
<div .container>
<h2>#{courseName course}
<table>
$maybe school <- schoolMB
<h4>#{schoolName school}
<tr>
<th #school>Fakultät/Institut
<td>
#{schoolName school}
$maybe descr <- courseDescription course
<tr>
<th #description>Beschreibung
<td>
<p>#{descr}
$maybe link <- courseLinkExternal course
<tr>
<th #website>Website
<td>
<a href=#{link}>#{link}
<tr>
<th #participants>Teilnehmer
<td>
#{participants}
$maybe capacity <- courseCapacity course
\ von #{capacity}
<tr>
<th #registration>Anmeldezeitraum
<td>
$maybe regFrom <- courseRegisterFrom course
#{formatTimeGerWD regFrom}
$maybe regTo <- courseRegisterTo course
\ bis #{formatTimeGerWD regTo}
$# if allowed to register
<div .course__registration>
<a href="#">Anmelden
$# <form method=post action=@{CourseR tid csh CourseShowR} enctype=#{regEnctype}>
$# ^{regWidget}
<div .container>
$maybe descr <- courseDescription course
<h2 #description>Beschreibung
<p> #{descr}
$maybe link <- courseLinkExternal course
<h4 #linl>Homepage
<a href=#{link}>#{link}
<div .tab-group>
<div .tab data-tab-name="Übungsblätter">
^{modal "#modal-toggler__new-sheet" Nothing}
<h3 .tab-title>Übungsblätter
<table .table.table-striped.table-hover>
<thead>
<tr>
<th>Blatt
<th>Abgabe ab
<th>Abgabe bis
<th>Bewertung</th>
<tbody>
<tr>
<td>
<a href="http://localhost:3000/course/S2018/ffp/ex/Blatt%201/show" role="button">Blatt 1
<td>Do 08.04.18
<td>Do 11.04.18
<td>NotGraded
<tr>
<td>
<a href="http://localhost:3000/course/S2018/ffp/ex/Blatt%201/show" role="button">Blatt 2
<td>Do 15.04.18
<td>Do 18.04.18
<td>NotGraded
<tr .no-hover.no-stripe>
<td>&nbsp;
<td>&nbsp;
<td>&nbsp;
<td>&nbsp;
<td>
<a href="/course/S2018/ffp/ex/new" #modal-toggler__new-sheet>Neues Übungsblatt anlegen
<div .tab data-tab-name="Übungsgruppen">
<h3 .tab-title>Übungsgruppen
<table .table.table-striped.table-hover>
<thead>
<tr>
<th>Name
<th>Termin
<th>Raum
<th>Studenten
<th>Tutor
<th>Anmeldung bis
<tbody>
<tr>
<td>
<a href="#">Gruppe 1
<td>Montag 10:00 - 12:00
<td>N/A
<td>2/10
<td>Tutor1 Tutoren
<td>Do 21.02.2019, 19:00
<tr>
<td>
<a href="#">Gruppe 2
<td>Montag 12:00 - 14:00
<td>N/A
<td>0/10
<td>Assistant1 Assistant
<td>Di 21.02.2017, 19:00
<div .tab data-tab-name="Klausuren">
<h3 .tab-title>Klausuren
<div>...

View File

@ -1,19 +0,0 @@
.course-header {
/*display: flex;
flex-direction: row;
justify-content: space-between;*/
}
.course-header__title {
align-self: baseline;
}
.course-header__info {
border: 1px solid var(--greybase);
padding: 13px;
align-self: center;
float: right;
}
.course-header__info table {
margin: 0;
}

View File

@ -106,6 +106,24 @@ table {
overflow: auto;
}
.table-striped {
tbody {
tr:not(.no-stripe):nth-child(even) {
background-color: #e8e8e8;
}
}
}
.table-hover {
tbody {
tr:not(.no-hover):hover {
background-color: #d8d8d8;
}
}
}
th, td {
text-align: left;
padding: 0 13px 0 7px;

View File

@ -40,7 +40,7 @@
^{modal ".toggler1" Nothing}
<a href="/" .btn.toggler1>Klick mich für Ajax-Test
<noscript>(Für Modals bitte JS aktivieren)</noscript>
^{modal ".toggler2" (Just "Test wegen Modal")}
^{modal ".toggler2" (Just "Test Inhalt für Modal")}
<div .btn.toggler2>Klick mich für Content-Test
<noscript>(Für Modals bitte JS aktivieren)</noscript>

View File

@ -10,6 +10,8 @@
var origParent = modal.parentNode;
function open(event) {
// disable modals for narrow screens
if (window.innerWidth < 768) return true;
if (event) {
event.preventDefault();
}
@ -64,7 +66,9 @@
replaceMe.classList.remove('replace-me');
replaceMe.innerText = '...loading';
if (replaceWith.length > 0) {
fetch(replaceWith).then(function(response) {
fetch(replaceWith, {
credentials: 'same-origin'
}).then(function(response) {
return response.text();
}).then(function(body) {
var modalContent = document.createElement('div');

View File

@ -1,18 +1,8 @@
<div .modal.js-modal #modal-#{modalId} data-trigger=#{modalTrigger} data-closeable=true>
$# primitive way of checking if this is supposed to be add a placeholder for async data.
$# modalContent is 'placeholder' if there should be a placeholder only.
$# 'placeholder' has length 11.
$if 11 == length modalContent
<div .replace-me>
$else
<h2>Neue Veranstaltung
#{modalContent}
<form>
<div .form-group>
<label .reactive-label for="inp1">Name
<input type="text" id="inp1">
<div .form-group>
<label .reactive-label for="inp2">Kürzel
<input type="text" id="inp2">
<div .form-group>
<label .reactive-label for="inp3">Semester
<input type="text" id="inp3">
<div .form-group>
<input type="submit" value="Submit">