Fix #878 -- Add multi-event widget

This commit is contained in:
Raphael Michel
2019-03-19 12:16:09 +01:00
parent ca7d55082b
commit 49e706a580
13 changed files with 1096 additions and 168 deletions

View File

@@ -36,6 +36,33 @@ var strings = {
'close': django.pgettext('widget', 'Close'),
'continue': django.pgettext('widget', 'Continue'),
'variations': django.pgettext('widget', 'See variations'),
'back_to_list': django.pgettext('widget', 'Choose a different event'),
'back': django.pgettext('widget', 'Back'),
'next_month': django.pgettext('widget', 'Next month'),
'previous_month': django.pgettext('widget', 'Previous month'),
'days': {
'MO': django.gettext('Mo'),
'TU': django.gettext('Tu'),
'WE': django.gettext('We'),
'TH': django.gettext('Th'),
'FR': django.gettext('Fr'),
'SA': django.gettext('Sa'),
'SU': django.gettext('Su'),
},
'months': {
'01': django.gettext('January'),
'02': django.gettext('February'),
'03': django.gettext('March'),
'04': django.gettext('April'),
'05': django.gettext('May'),
'06': django.gettext('June'),
'07': django.gettext('July'),
'08': django.gettext('August'),
'09': django.gettext('September'),
'10': django.gettext('October'),
'11': django.gettext('November'),
'12': django.gettext('December'),
}
};
var setCookie = function (cname, cvalue, exdays) {
@@ -51,6 +78,12 @@ var getCookie = function (name) {
else return null;
};
var padNumber = function(number, size) {
var s = String(number);
while (s.length < (size || 2)) {s = "0" + s;}
return s;
};
/* HTTP API Call helpers */
var api = {
'_getXHR': function () {
@@ -181,9 +214,9 @@ Vue.component('availbox', {
},
waiting_list_url: function () {
if (this.item.has_variations) {
return this.$root.event_url + 'w/' + widget_id + '/waitinglist/?item=' + this.item.id + '&var=' + this.variation.id;
return this.$root.target_url + 'w/' + widget_id + '/waitinglist/?item=' + this.item.id + '&var=' + this.variation.id;
} else {
return this.$root.event_url + 'w/' + widget_id + '/waitinglist/?item=' + this.item.id;
return this.$root.target_url + 'w/' + widget_id + '/waitinglist/?item=' + this.item.id;
}
}
}
@@ -405,13 +438,17 @@ var shared_methods = {
this.$root.overlay.frame_loading = true;
this.async_task_interval = 100;
api._postFormJSON(url, this.$refs.form, this.buy_callback, this.buy_error_callback);
var form = this.$refs.form;
if (form === undefined) {
form = this.$refs.formcomp.$refs.form;
}
api._postFormJSON(url, form, this.buy_callback, this.buy_error_callback);
}
},
buy_error_callback: function (xhr, data) {
if (xhr.status === 405 && typeof xhr.responseURL !== "undefined") {
// Likely a redirect!
this.$root.event_url = xhr.responseURL.substr(0, xhr.responseURL.indexOf("/cart/add") - 18);
this.$root.target_url = xhr.responseURL.substr(0, xhr.responseURL.indexOf("/cart/add") - 18);
this.$root.overlay.frame_loading = false;
this.buy();
return;
@@ -435,7 +472,7 @@ var shared_methods = {
setCookie(this.$root.cookieName, data.cart_id, 30);
}
if (data.redirect.substr(0, 1) === '/') {
data.redirect = this.$root.event_url.replace(/^([^\/]+:\/\/[^\/]+)\/.*$/, "$1") + data.redirect;
data.redirect = this.$root.target_url.replace(/^([^\/]+:\/\/[^\/]+)\/.*$/, "$1") + data.redirect;
}
var url = data.redirect;
if (url.indexOf('?')) {
@@ -456,7 +493,7 @@ var shared_methods = {
} else {
this.async_task_id = data.async_id;
if (data.check_url) {
this.async_task_check_url = this.$root.event_url.replace(/^([^\/]+:\/\/[^\/]+)\/.*$/, "$1") + data.check_url;
this.async_task_check_url = this.$root.target_url.replace(/^([^\/]+:\/\/[^\/]+)\/.*$/, "$1") + data.check_url;
}
this.async_task_timeout = window.setTimeout(this.buy_check, this.async_task_interval);
this.async_task_interval = 250;
@@ -480,7 +517,7 @@ var shared_methods = {
iframe.src = redirect_url;
},
resume: function () {
var redirect_url = this.$root.event_url + 'w/' + widget_id + '/?iframe=1&locale=' + lang;
var redirect_url = this.$root.target_url + 'w/' + widget_id + '/?iframe=1&locale=' + lang;
if (this.$root.cart_id) {
redirect_url += '&take_cart_id=' + this.$root.cart_id;
}
@@ -504,6 +541,7 @@ var shared_widget_data = function () {
async_task_timeout: null,
async_task_interval: 100,
voucher: null,
mobile: false,
}
};
@@ -586,10 +624,16 @@ Vue.component('pretix-overlay', {
}
});
Vue.component('pretix-widget', {
template: ('<div class="pretix-widget-wrapper">'
+ '<div class="pretix-widget">'
+ shared_loading_fragment
Vue.component('pretix-widget-event-form', {
template: ('<div class="pretix-widget-event-form">'
+ '<div class="pretix-widget-event-list-back" v-if="$root.events || $root.weeks">'
+ '<a href="#" @click.prevent="back_to_list">&lsaquo; '
+ strings['back_to_list']
+ '</a>'
+ '</div>'
+ '<div class="pretix-widget-event-header" v-if="$root.events || $root.weeks">'
+ '<strong>{{ $root.name }}</strong>'
+ '</div>'
+ '<form method="post" :action="$root.formTarget" ref="form" target="_blank">'
+ '<input type="hidden" name="_voucher_code" :value="$root.voucher_code" v-if="$root.voucher_code">'
+ '<input type="hidden" name="subevent" :value="$root.subevent" />'
@@ -597,7 +641,7 @@ Vue.component('pretix-widget', {
+ '<div class="pretix-widget-error-message" v-if="$root.error">{{ $root.error }}</div>'
+ '<div class="pretix-widget-info-message pretix-widget-clickable"'
+ ' v-if="$root.cart_exists">'
+ '<button @click.prevent="resume" class="pretix-widget-resume-button" type="button">'
+ '<button @click.prevent="$parent.resume" class="pretix-widget-resume-button" type="button">'
+ strings['resume_checkout']
+ '</button>'
+ strings['cart_exists']
@@ -605,7 +649,7 @@ Vue.component('pretix-widget', {
+ '</div>'
+ '<category v-for="category in this.$root.categories" :category="category" :key="category.id"></category>'
+ '<div class="pretix-widget-action" v-if="$root.display_add_to_cart">'
+ '<button @click="buy" type="submit">' + strings.buy + '</button>'
+ '<button @click="$parent.buy" type="submit">' + strings.buy + '</button>'
+ '</div>'
+ '</form>'
+ '<form method="get" :action="$root.voucherFormTarget" target="_blank" '
@@ -613,15 +657,262 @@ Vue.component('pretix-widget', {
+ '<div class="pretix-widget-voucher">'
+ '<h3 class="pretix-widget-voucher-headline">'+ strings['redeem_voucher'] +'</h3>'
+ '<div class="pretix-widget-voucher-input-wrap">'
+ '<input class="pretix-widget-voucher-input" type="text" v-model="voucher" name="voucher" placeholder="'+strings.voucher_code+'">'
+ '<input class="pretix-widget-voucher-input" type="text" v-model="$parent.voucher" name="voucher" placeholder="'+strings.voucher_code+'">'
+ '</div>'
+ '<input type="hidden" name="subevent" :value="$root.subevent" />'
+ '<input type="hidden" name="locale" value="' + lang + '" />'
+ '<div class="pretix-widget-voucher-button-wrap">'
+ '<button @click="redeem">' + strings.redeem + '</button>'
+ '<button @click="$parent.redeem">' + strings.redeem + '</button>'
+ '</div>'
+ '</div>'
+ '</form>'
+ '</div>'
),
methods: {
back_to_list: function() {
this.$root.target_url = this.$root.parent_stack.pop();
this.$root.error = null;
this.$root.subevent = null;
if (this.$root.events !== undefined) {
this.$root.view = "events";
} else {
this.$root.view = "weeks";
}
}
}
});
Vue.component('pretix-widget-event-list-entry', {
template: ('<a :class="classObject" @click.prevent="select">'
+ '<div class="pretix-widget-event-list-entry-name">{{ event.name }}</div>'
+ '<div class="pretix-widget-event-list-entry-date">{{ event.date_range }}</div>'
+ '<div class="pretix-widget-event-list-entry-availability"><span>{{ event.availability.text }}</span></div>'
+ '</a>'),
props: {
event: Object
},
computed: {
classObject: function () {
var o = {
'pretix-widget-event-list-entry': true
};
o['pretix-widget-event-availability-' + this.event.availability.color] = true;
return o
}
},
methods: {
select: function () {
this.$root.parent_stack.push(this.$root.target_url);
this.$root.target_url = this.event.event_url;
this.$root.error = null;
this.$root.subevent = this.event.subevent;
this.$root.loading++;
this.$root.reload();
}
}
});
Vue.component('pretix-widget-event-list', {
template: ('<div class="pretix-widget-event-list">'
+ '<div class="pretix-widget-back" v-if="$root.weeks || $root.parent_stack.length > 0">'
+ '<a href="#" @click.prevent="back_to_calendar">&lsaquo; '
+ strings['back']
+ '</a>'
+ '</div>'
+ '<pretix-widget-event-list-entry v-for="event in $root.events" :event="event" :key="event.url"></pretix-widget-event-list-entry>'
+ '</div>'),
methods: {
back_to_calendar: function () {
if (this.$root.weeks) {
this.$root.events = undefined;
this.$root.view = "weeks";
} else {
this.$root.loading++;
this.$root.target_url = this.$root.parent_stack.pop();
this.$root.error = null;
this.$root.reload();
}
},
}
});
Vue.component('pretix-widget-event-calendar-event', {
template: ('<a :class="classObject" @click.prevent="select">'
+ '<strong class="pretix-widget-event-calendar-event-name">'
+ '{{ event.name }}'
+ '</strong>'
+ '<div class="pretix-widget-event-calendar-event-date" v-if="!event.continued && event.time">{{ event.time }}</div>'
+ '<div class="pretix-widget-event-calendar-event-availability" v-if="!event.continued">{{ event.availability.text }}</div>'
+ '</a>'),
props: {
event: Object
},
computed: {
classObject: function () {
var o = {
'pretix-widget-event-calendar-event': true
};
o['pretix-widget-event-availability-' + this.event.availability.color] = true;
return o
}
},
methods: {
select: function () {
this.$root.parent_stack.push(this.$root.target_url);
this.$root.target_url = this.event.event_url;
this.$root.error = null;
this.$root.subevent = this.event.subevent;
this.$root.loading++;
this.$root.reload();
}
}
});
Vue.component('pretix-widget-event-calendar-cell', {
template: ('<td :class="classObject" @click.prevent="selectDay">'
+ '<div class="pretix-widget-event-calendar-day" v-if="day">'
+ '{{ daynum }}'
+ '</div>'
+ '<div class="pretix-widget-event-calendar-events" v-if="day">'
+ '<pretix-widget-event-calendar-event v-for="e in day.events" :event="e"></pretix-widget-event-calendar-event>'
+ '</div>'
+ '</td>'),
props: {
day: Object
},
methods: {
selectDay: function () {
if (!this.day || !this.day.events.length || !this.$parent.$parent.$parent.mobile) {
return;
}
if (this.day.events.length === 1) {
var ev = this.day.events[0];
this.$root.parent_stack.push(this.$root.target_url);
this.$root.target_url = ev.event_url;
this.$root.error = null;
this.$root.subevent = ev.subevent;
this.$root.loading++;
this.$root.reload();
} else {
this.$root.events = this.day.events;
this.$root.view = "events";
}
}
},
computed: {
daynum: function () {
if (!this.day) {
return;
}
return this.day.date.substr(8);
},
classObject: function () {
var o = {};
if (this.day && this.day.events.length > 0) {
o['pretix-widget-has-events'] = true;
var best = 'red';
for (var i = 0; i < this.day.events.length; i++) {
var ev = this.day.events[i];
if (ev.availability.color === 'green') {
best = 'green';
} else if (ev.availability.color === 'orange' || best !== 'green') {
best = 'orange'
}
}
o['pretix-widget-day-availability-' + best] = true;
}
return o
}
}
});
Vue.component('pretix-widget-event-calendar-row', {
template: ('<tr>'
+ '<pretix-widget-event-calendar-cell v-for="d in week" :day="d"></pretix-widget-event-calendar-cell>'
+ '</tr>'),
props: {
week: Array
},
});
Vue.component('pretix-widget-event-calendar', {
template: ('<div class="pretix-widget-event-calendar" ref="calendar">'
+ '<div class="pretix-widget-back" v-if="$root.events !== undefined">'
+ '<a href="#" @click.prevent="back_to_list">&lsaquo; '
+ strings['back']
+ '</a>'
+ '</div>'
+ '<div class="pretix-widget-event-calendar-head">'
+ '<a class="pretix-widget-event-calendar-previous-month" href="#" @click.prevent="prevmonth">&laquo; '
+ strings['previous_month']
+ '</a> '
+ '<strong>{{ monthname }}</strong> '
+ '<a class="pretix-widget-event-calendar-next-month" href="#" @click.prevent="nextmonth">'
+ strings['next_month']
+ ' &raquo;</a>'
+ '</div>'
+ '<table class="pretix-widget-event-calendar-table">'
+ '<thead>'
+ '<tr>'
+ '<th>' + strings['days']['MO'] + '</th>'
+ '<th>' + strings['days']['TU'] + '</th>'
+ '<th>' + strings['days']['WE'] + '</th>'
+ '<th>' + strings['days']['TH'] + '</th>'
+ '<th>' + strings['days']['FR'] + '</th>'
+ '<th>' + strings['days']['SA'] + '</th>'
+ '<th>' + strings['days']['SU'] + '</th>'
+ '</tr>'
+ '</thead>'
+ '<tbody>'
+ '<pretix-widget-event-calendar-row v-for="week in $root.weeks" :week="week"></pretix-widget-event-calendar-row>'
+ '</tbody>'
+ '</table>'
+ '</div>'),
computed: {
monthname: function () {
return strings['months'][this.$root.date.substr(5, 2)] + ' ' + this.$root.date.substr(0, 4);
}
},
methods: {
back_to_list: function () {
this.$root.weeks = undefined;
this.$root.view = "events";
},
prevmonth: function () {
var curMonth = parseInt(this.$root.date.substr(5, 2));
var curYear = parseInt(this.$root.date.substr(0, 4));
curMonth--;
if (curMonth < 1) {
curMonth = 12;
curYear--;
}
this.$root.date = String(curYear) + "-" + padNumber(curMonth, 2) + "-01";
this.$root.loading++;
this.$root.reload();
},
nextmonth: function () {
var curMonth = parseInt(this.$root.date.substr(5, 2));
var curYear = parseInt(this.$root.date.substr(0, 4));
curMonth++;
if (curMonth > 12) {
curMonth = 1;
curYear++;
}
this.$root.date = String(curYear) + "-" + padNumber(curMonth, 2) + "-01";
this.$root.loading++;
this.$root.reload();
}
},
});
Vue.component('pretix-widget', {
template: ('<div class="pretix-widget-wrapper" ref="wrapper">'
+ '<div :class="classObject">'
+ shared_loading_fragment
+ '<div class="pretix-widget-error-message" v-if="$root.error && $root.view !== \'event\'">{{ $root.error }}</div>'
+ '<pretix-widget-event-form ref="formcomp" v-if="$root.view === \'event\'"></pretix-widget-event-form>'
+ '<pretix-widget-event-list v-if="$root.view === \'events\'"></pretix-widget-event-list>'
+ '<pretix-widget-event-calendar v-if="$root.view === \'weeks\'"></pretix-widget-event-calendar>'
+ '<div class="pretix-widget-clear"></div>'
+ '<div class="pretix-widget-attribution">'
+ strings.poweredby
@@ -632,6 +923,18 @@ Vue.component('pretix-widget', {
),
data: shared_widget_data,
methods: shared_methods,
mounted: function () {
this.mobile = this.$refs.wrapper.clientWidth <= 800;
},
computed: {
classObject: function () {
o = {'pretix-widget': true};
if (this.mobile) {
o['pretix-widget-mobile'] = true;
}
return o;
}
}
});
Vue.component('pretix-button', {
@@ -674,9 +977,9 @@ var shared_root_methods = {
reload: function () {
var url;
if (this.$root.subevent) {
url = this.$root.event_url + this.$root.subevent + '/widget/product_list?lang=' + lang;
url = this.$root.target_url + this.$root.subevent + '/widget/product_list?lang=' + lang;
} else {
url = this.$root.event_url + 'widget/product_list?lang=' + lang;
url = this.$root.target_url + 'widget/product_list?lang=' + lang;
}
var cart_id = getCookie(this.cookieName);
if (this.$root.voucher_code) {
@@ -685,6 +988,12 @@ var shared_root_methods = {
if (cart_id) {
url += "&cart_id=" + cart_id;
}
if (this.$root.date !== null) {
url += "&year=" + this.$root.date.substr(0, 4) + "&month=" + this.$root.date.substr(5, 2);
}
if (this.$root.style !== null) {
url = url + '&style=' + this.$root.style;
}
var root = this.$root;
api._getJSON(url, function (data, xhr) {
if (typeof xhr.responseURL !== "undefined" && xhr.responseURL !== url) {
@@ -692,21 +1001,34 @@ var shared_root_methods = {
if (root.subevent) {
new_url = new_url.substr(0, new_url.lastIndexOf("/", new_url.length - 1) + 1);
}
root.event_url = new_url;
root.target_url = new_url;
root.reload();
return;
}
root.categories = data.items_by_category;
root.currency = data.currency;
root.display_net_prices = data.display_net_prices;
root.error = data.error;
root.display_add_to_cart = data.display_add_to_cart;
root.waiting_list_enabled = data.waiting_list_enabled;
root.show_variations_expanded = data.show_variations_expanded;
root.cart_id = cart_id;
root.cart_exists = data.cart_exists;
root.vouchers_exist = data.vouchers_exist;
root.itemnum = data.itemnum;
if (data.weeks !== undefined) {
root.weeks = data.weeks;
root.date = data.date;
root.events = undefined;
root.view = "weeks";
} else if (data.events !== undefined) {
root.events = data.events;
root.weeks = undefined;
root.view = "events";
} else {
root.view = "event";
root.name = data.name;
root.categories = data.items_by_category;
root.currency = data.currency;
root.display_net_prices = data.display_net_prices;
root.error = data.error;
root.display_add_to_cart = data.display_add_to_cart;
root.waiting_list_enabled = data.waiting_list_enabled;
root.show_variations_expanded = data.show_variations_expanded;
root.cart_id = cart_id;
root.cart_exists = data.cart_exists;
root.vouchers_exist = data.vouchers_exist;
root.itemnum = data.itemnum;
}
if (root.loading > 0) {
root.loading--;
}
@@ -718,15 +1040,22 @@ var shared_root_methods = {
root.loading--;
}
});
},
choose_event: function (event) {
root.target_url = event.event_url;
this.$root.error = null;
root.subevent = event.subevent;
root.loading++;
root.reload();
}
};
var shared_root_computed = {
cookieName: function () {
return "pretix_widget_" + this.event_url.replace(/[^a-zA-Z0-9]+/g, "_");
return "pretix_widget_" + this.target_url.replace(/[^a-zA-Z0-9]+/g, "_");
},
voucherFormTarget: function () {
var form_target = this.event_url + 'w/' + widget_id + '/redeem?iframe=1&locale=' + lang;
var form_target = this.target_url + 'w/' + widget_id + '/redeem?iframe=1&locale=' + lang;
var cookie = getCookie(this.cookieName);
if (cookie) {
form_target += "&take_cart_id=" + cookie;
@@ -737,11 +1066,11 @@ var shared_root_computed = {
return form_target;
},
formTarget: function () {
var checkout_url = "/" + this.event_url.replace(/^[^\/]+:\/\/([^\/]+)\//, "") + "w/" + widget_id + "/";
var checkout_url = "/" + this.target_url.replace(/^[^\/]+:\/\/([^\/]+)\//, "") + "w/" + widget_id + "/";
if (!this.$root.cart_exists) {
checkout_url += "checkout/start";
}
var form_target = this.event_url + 'w/' + widget_id + '/cart/add?iframe=1&next=' + encodeURIComponent(checkout_url);
var form_target = this.target_url + 'w/' + widget_id + '/cart/add?iframe=1&next=' + encodeURIComponent(checkout_url);
var cookie = getCookie(this.cookieName);
if (cookie) {
form_target += "&take_cart_id=" + cookie;
@@ -812,12 +1141,13 @@ function get_ga_client_id(tracking_id) {
}
var create_widget = function (element) {
var event_url = element.attributes.event.value;
if (!event_url.match(/\/$/)) {
event_url += "/";
var target_url = element.attributes.event.value;
if (!target_url.match(/\/$/)) {
target_url += "/";
}
var voucher = element.attributes.voucher ? element.attributes.voucher.value : null;
var subevent = element.attributes.subevent ? element.attributes.subevent.value : null;
var style = element.attributes.style ? element.attributes.style.value : null;
var skip_ssl = element.attributes["skip-ssl-check"] ? true : false;
var disable_vouchers = element.attributes["disable-vouchers"] ? true : false;
var widget_data = JSON.parse(JSON.stringify(window.PretixWidget.widget_data));
@@ -836,16 +1166,23 @@ var create_widget = function (element) {
el: element,
data: function () {
return {
event_url: event_url,
target_url: target_url,
parent_stack: [],
subevent: subevent,
is_button: false,
categories: null,
currency: null,
name: null,
voucher_code: voucher,
display_net_prices: false,
show_variations_expanded: false,
skip_ssl: skip_ssl,
style: style,
error: null,
weeks: null,
date: null,
events: null,
view: null,
display_add_to_cart: false,
widget_data: widget_data,
loading: 1,
@@ -868,9 +1205,9 @@ var create_widget = function (element) {
};
var create_button = function (element) {
var event_url = element.attributes.event.value;
if (!event_url.match(/\/$/)) {
event_url += "/";
var target_url = element.attributes.event.value;
if (!target_url.match(/\/$/)) {
target_url += "/";
}
var voucher = element.attributes.voucher ? element.attributes.voucher.value : null;
var subevent = element.attributes.subevent ? element.attributes.subevent.value : null;
@@ -902,7 +1239,7 @@ var create_button = function (element) {
el: element,
data: function () {
return {
event_url: event_url,
target_url: target_url,
subevent: subevent,
is_button: true,
skip_ssl: skip_ssl,

View File

@@ -116,9 +116,9 @@
padding: 10px;
text-align: center;
margin: 10px 0;
background-color: $alert-danger-bg;
border-color: $alert-danger-border;
color: $alert-danger-text;
background-color: white;
border: 2px solid $brand-danger;
color: $brand-danger;
border-radius: $alert-border-radius;
}
@@ -345,6 +345,136 @@
max-height: 1000px;
overflow: hidden;
}
.pretix-widget-event-header {
padding-top: 10px;
text-align: center;
}
.pretix-widget-event-list-back {
padding-top: 10px;
text-align: center;
display: block;
a {
display: block;
}
}
.pretix-widget-back {
padding-bottom: 10px;
text-align: center;
display: block;
a {
display: block;
}
}
.pretix-widget-event-list {
padding: 10px 0;
cursor: pointer;
}
.pretix-widget-event-list-entry {
display: flex;
flex-direction: row;
padding: 5px 0;
flex-wrap: wrap;
color: $text-color;
&:hover, &:active, &:focus {
background: $gray-lighter;
text-decoration: none;
}
.pretix-widget-event-list-entry-name {
width: 50%;
padding: 5px;
box-sizing: border-box;
}
.pretix-widget-event-list-entry-date {
width: 25%;
padding: 5px;
box-sizing: border-box;
}
.pretix-widget-event-list-entry-availability {
width: 25%;
text-align: right;
padding: 7px 5px 3px;
box-sizing: border-box;
span {
display: inline;
padding: 2px 6px 3px;
font-size: 75%;
font-weight: bold;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: 4px;
}
}
}
.pretix-widget-event-availability-orange .pretix-widget-event-list-entry-availability span,
.pretix-widget-event-availability-orange.pretix-widget-event-calendar-event {
background-color: $brand-warning;
}
.pretix-widget-event-availability-none .pretix-widget-event-list-entry-availability span {
background-color: $brand-primary;
}
.pretix-widget-event-availability-green .pretix-widget-event-list-entry-availability span,
.pretix-widget-event-availability-green.pretix-widget-event-calendar-event {
background-color: $brand-success;
}
.pretix-widget-event-availability-red .pretix-widget-event-list-entry-availability span,
.pretix-widget-event-availability-red.pretix-widget-event-calendar-event {
background-color: $brand-danger;
}
.pretix-widget-event-calendar {
padding-top: 10px;
.pretix-widget-event-calendar-head {
display: flex;
flex-direction: row;
strong {
width: 50%;
text-align: center;
display: block;
}
.pretix-widget-event-calendar-next-month, .pretix-widget-event-calendar-previous-month {
display: block;
width: 25%;
}
.pretix-widget-event-calendar-next-month {
text-align: right;
}
}
.pretix-widget-event-calendar-event {
display: block;
border-radius: 4px;
padding: 5px;
color: white;
cursor: pointer;
margin-bottom: 5px;
&:last-child {
margin-bottom: 0;
}
&:hover {
text-decoration: none;
}
}
.pretix-widget-event-calendar-table {
width: 100%;
th, td {
width: 14.285714285714286%;
vertical-align: top;
padding: 10px 5px;
}
}
.pretix-widget-event-calendar-day {
font-weight: bold;
}
}
}
@keyframes pretix-widget-bounce-in {
@@ -504,28 +634,71 @@
fill: $brand-primary;
}
@media (max-width: $screen-sm-max) {
.pretix-widget {
.pretix-widget-item-info-col {
.pretix-widget.pretix-widget-mobile {
.pretix-widget-item-info-col {
width: 100%;
float: none;
margin-bottom: 5px;
}
.pretix-widget-item-price-col, .pretix-widget-item-availability-col {
width: 50%;
}
.pretix-widget-action {
width: 100%;
margin-left: 0;
}
.pretix-widget-voucher-input-wrap {
width: 100%;
float: none;
}
.pretix-widget-voucher-button-wrap {
width: 100%;
float: none;
margin-top: 10px;
}
.pretix-widget-event-list-entry {
.pretix-widget-event-list-entry-name {
width: 100%;
float: none;
margin-bottom: 5px;
}
.pretix-widget-item-price-col, .pretix-widget-item-availability-col {
.pretix-widget-event-list-entry-date {
width: 50%;
}
.pretix-widget-action {
width: 100%;
margin-left: 0;
.pretix-widget-event-list-entry-availability {
width: 50%;
}
.pretix-widget-voucher-input-wrap {
width: 100%;
float: none;
}
.pretix-widget-event-calendar {
.pretix-widget-event-calendar-events {
display: none;
}
.pretix-widget-voucher-button-wrap {
width: 100%;
float: none;
margin-top: 10px;
td.pretix-widget-has-events {
background: $brand-primary;
color: white;
cursor: pointer;
&.pretix-widget-day-availability-red {
background: $brand-danger;
}
&.pretix-widget-day-availability-green {
background: $brand-success;
}
&.pretix-widget-day-availability-orange {
background: $brand-warning;
}
}
.pretix-widget-event-calendar-head {
display: block;
strong {
width: 100%;
display: block;
}
.pretix-widget-event-calendar-next-month, .pretix-widget-event-calendar-previous-month {
display: block;
width: 100%;
text-align: center;
}
}
}
}